"use client";

import { useEffect, useMemo, useState } from "react";
import DatePicker from "react-multi-date-picker";
import DateObject from "react-date-object";
import persian from "react-date-object/calendars/persian";
import gregorian from "react-date-object/calendars/gregorian";
import persian_fa from "react-date-object/locales/persian_fa";
import gregorian_en from "react-date-object/locales/gregorian_en";
import {
  dateValueToJalali,
  formatPersianDateTime,
  getDateFromJalaliDateTime,
  jalaliDateTimeToUtcIso,
  jalaliDateToGregorianString,
  type JalaliDateParts,
} from "@/lib/persianDate";

type PersianDateFieldProps = {
  label: string;
  value: string;
  onChange: (value: string) => void;
  mode?: "date" | "datetime";
  required?: boolean;
  placeholder?: string;
};

function createDateObject(parts: JalaliDateParts | null) {
  if (!parts) return null;

  return new DateObject({
    calendar: persian,
    locale: persian_fa,
    year: parts.year,
    month: parts.month,
    day: parts.day,
  });
}

function getInitialTime(value: string, mode: "date" | "datetime") {
  const parsedValue = dateValueToJalali(value, mode);
  return parsedValue?.time || "12:00";
}

export default function PersianDateField({
  label,
  value,
  onChange,
  mode = "date",
  required = false,
  placeholder = "انتخاب تاریخ شمسی",
}: PersianDateFieldProps) {
  const parsedValue = useMemo(() => dateValueToJalali(value, mode), [mode, value]);
  const pickerValue = useMemo(() => createDateObject(parsedValue), [parsedValue]);
  const [time, setTime] = useState(getInitialTime(value, mode));

  useEffect(() => {
    setTime(getInitialTime(value, mode));
  }, [mode, value]);

  function emitChange(nextDate: DateObject | null, nextTime: string) {
    if (!nextDate) {
      onChange("");
      return;
    }

    const year = Number(nextDate.year);
    const month = Number(nextDate.month.number);
    const day = Number(nextDate.day);

    if (mode === "date") {
      onChange(jalaliDateToGregorianString(year, month, day));
      return;
    }

    onChange(jalaliDateTimeToUtcIso(year, month, day, nextTime));
  }

  const preview = useMemo(() => {
    if (!parsedValue) return "";
    if (mode === "date") return "";

    return formatPersianDateTime(
      getDateFromJalaliDateTime(parsedValue.year, parsedValue.month, parsedValue.day, time)
    );
  }, [mode, parsedValue, time]);

  return (
    <div className="space-y-2">
      <label className="block text-sm font-medium text-slate-700">{label}</label>

      <DatePicker
        value={pickerValue}
        onChange={(selected) => emitChange((selected as DateObject | null) ?? null, time)}
        calendar={persian}
        locale={persian_fa}
        format="YYYY/MM/DD"
        calendarPosition="bottom-right"
        editable={false}
        required={required}
        placeholder={placeholder}
        inputClass="w-full rounded-2xl border border-slate-200 bg-white px-4 py-3 text-right text-slate-900 shadow-sm outline-none transition focus:border-emerald-400 focus:ring-2 focus:ring-emerald-200"
        containerClassName="block w-full"
        weekDays={[
          ["شنبه", "ش"],
          ["یکشنبه", "ی"],
          ["دوشنبه", "د"],
          ["سه‌شنبه", "س"],
          ["چهارشنبه", "چ"],
          ["پنجشنبه", "پ"],
          ["جمعه", "ج"],
        ]}
      />

      {pickerValue && (
        <div className="rounded-xl bg-slate-50 px-3 py-2 text-xs text-slate-500">
          {mode === "date"
            ? `تاریخ انتخاب‌شده: ${pickerValue.format("dddd DD MMMM YYYY")}`
            : preview}
        </div>
      )}

      {mode === "datetime" && (
        <div className="grid grid-cols-2 gap-3">
          <div>
            <label className="mb-1 block text-xs font-medium text-slate-600">ساعت</label>
            <select
              value={time.split(":")[0]}
              onChange={(event) => {
                const nextTime = `${event.target.value}:${time.split(":")[1]}`;
                setTime(nextTime);
                emitChange(pickerValue, nextTime);
              }}
              className="w-full rounded-xl border border-slate-200 bg-white px-3 py-2 text-slate-900 outline-none transition focus:border-emerald-400 focus:ring-2 focus:ring-emerald-200"
            >
              {Array.from({ length: 24 }, (_, index) => String(index).padStart(2, "0")).map((hour) => (
                <option key={hour} value={hour}>
                  {new Intl.NumberFormat("fa-IR").format(Number(hour))}
                </option>
              ))}
            </select>
          </div>

          <div>
            <label className="mb-1 block text-xs font-medium text-slate-600">دقیقه</label>
            <select
              value={time.split(":")[1]}
              onChange={(event) => {
                const nextTime = `${time.split(":")[0]}:${event.target.value}`;
                setTime(nextTime);
                emitChange(pickerValue, nextTime);
              }}
              className="w-full rounded-xl border border-slate-200 bg-white px-3 py-2 text-slate-900 outline-none transition focus:border-emerald-400 focus:ring-2 focus:ring-emerald-200"
            >
              {Array.from({ length: 60 }, (_, index) => String(index).padStart(2, "0")).map((minute) => (
                <option key={minute} value={minute}>
                  {new Intl.NumberFormat("fa-IR").format(Number(minute))}
                </option>
              ))}
            </select>
          </div>
        </div>
      )}
    </div>
  );
}
