"use client";

import * as React from "react";
import { cn } from "@/lib/utils";
import { useI18n, type TranslationKey } from "@/lib/i18n";

export type RecurrenceMode = "daily" | "weekly" | "biweekly" | "monthly" | "yearly";

export type RecurrenceRule = {
  type: "hourly" | "daily" | "weekly" | "monthly" | "yearly";
  interval?: number;
  byWeekday?: number;
  byMonthday?: number;
};

interface RecurrencePickerProps {
  value?: RecurrenceRule;
  onChange?: (rule: RecurrenceRule) => void;
  dueDate?: Date;
  className?: string;
}

const WEEKDAYS = [
  { value: 0, labelKey: "sun" },
  { value: 1, labelKey: "mon" },
  { value: 2, labelKey: "tue" },
  { value: 3, labelKey: "wed" },
  { value: 4, labelKey: "thu" },
  { value: 5, labelKey: "fri" },
  { value: 6, labelKey: "sat" },
] as const;

const MONTHS = [
  { value: 1, labelKey: "jan" },
  { value: 2, labelKey: "feb" },
  { value: 3, labelKey: "mar" },
  { value: 4, labelKey: "apr" },
  { value: 5, labelKey: "may" },
  { value: 6, labelKey: "jun" },
  { value: 7, labelKey: "jul" },
  { value: 8, labelKey: "aug" },
  { value: 9, labelKey: "sep" },
  { value: 10, labelKey: "oct" },
  { value: 11, labelKey: "nov" },
  { value: 12, labelKey: "dec" },
] as const;

export function RecurrencePicker({
  value,
  onChange,
  dueDate,
  className,
}: RecurrencePickerProps) {
  const { t } = useI18n();
  
  // Derive mode from value
  const getMode = (): RecurrenceMode => {
    if (!value) return "daily";
    if (value.type === "weekly" && value.interval === 2) return "biweekly";
    if (value.type === "weekly") return "weekly";
    if (value.type === "monthly") return "monthly";
    if (value.type === "yearly") return "yearly";
    return "daily";
  };
  
  const [mode, setMode] = React.useState<RecurrenceMode>(getMode);
  const [selectedWeekday, setSelectedWeekday] = React.useState<number>(
    value?.byWeekday ?? (dueDate ? dueDate.getDay() : new Date().getDay())
  );
  const [selectedMonthday, setSelectedMonthday] = React.useState<number>(
    value?.byMonthday ?? (dueDate ? dueDate.getDate() : new Date().getDate())
  );
  const [selectedMonth, setSelectedMonth] = React.useState<number>(
    dueDate ? dueDate.getMonth() + 1 : new Date().getMonth() + 1
  );
  const [selectedYearDay, setSelectedYearDay] = React.useState<number>(
    dueDate ? dueDate.getDate() : new Date().getDate()
  );

  // Sync internal state when value changes from parent
  React.useEffect(() => {
    setMode(getMode());
    if (value?.byWeekday !== undefined) {
      setSelectedWeekday(value.byWeekday);
    }
    if (value?.byMonthday !== undefined) {
      setSelectedMonthday(value.byMonthday);
      setSelectedYearDay(value.byMonthday);
    }
  }, [value]);

  // Build rule and call onChange
  const buildRule = React.useCallback((
    newMode: RecurrenceMode,
    weekday: number,
    monthday: number,
    month: number,
    yearDay: number
  ): RecurrenceRule => {
    switch (newMode) {
      case "daily":
        return { type: "daily", interval: 1 };
      case "weekly":
        return { type: "weekly", interval: 1, byWeekday: weekday };
      case "biweekly":
        return { type: "weekly", interval: 2, byWeekday: weekday };
      case "monthly":
        return { type: "monthly", interval: 1, byMonthday: monthday };
      case "yearly":
        // For yearly, we store the day in byMonthday
        // The month is derived from the dueDate which user sets separately
        return { type: "yearly", interval: 1, byMonthday: yearDay };
      default:
        return { type: "daily", interval: 1 };
    }
  }, []);

  const handleModeChange = (newMode: RecurrenceMode) => {
    setMode(newMode);
    onChange?.(buildRule(newMode, selectedWeekday, selectedMonthday, selectedMonth, selectedYearDay));
  };

  const handleWeekdayChange = (weekday: number) => {
    setSelectedWeekday(weekday);
    onChange?.(buildRule(mode, weekday, selectedMonthday, selectedMonth, selectedYearDay));
  };

  const handleMonthdayChange = (day: number) => {
    setSelectedMonthday(day);
    onChange?.(buildRule(mode, selectedWeekday, day, selectedMonth, selectedYearDay));
  };

  const handleYearDayChange = (day: number) => {
    setSelectedYearDay(day);
    onChange?.(buildRule(mode, selectedWeekday, selectedMonthday, selectedMonth, day));
  };

  const handleMonthChange = (month: number) => {
    setSelectedMonth(month);
    // When month changes, also update yearDay if it exceeds the month's days
    const maxDays = getDaysInMonth(month);
    const newDay = Math.min(selectedYearDay, maxDays);
    setSelectedYearDay(newDay);
    onChange?.(buildRule(mode, selectedWeekday, selectedMonthday, month, newDay));
  };

  // Get days in a specific month (for year 2024 as reference)
  const getDaysInMonth = (month: number): number => {
    const daysInMonth = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    return daysInMonth[month - 1] || 31;
  };

  // Generate preview text
  const getPreviewText = (): string => {
    const time = dueDate 
      ? `${dueDate.getHours().toString().padStart(2, "0")}:${dueDate.getMinutes().toString().padStart(2, "0")}`
      : "";
    
    switch (mode) {
      case "daily":
        return t("recurrencePreviewDaily" as TranslationKey, { time });
      case "weekly":
        return t("recurrencePreviewWeekly" as TranslationKey, { 
          weekday: t(WEEKDAYS[selectedWeekday].labelKey as TranslationKey),
          time 
        });
      case "biweekly":
        return t("recurrencePreviewBiweekly" as TranslationKey, { 
          weekday: t(WEEKDAYS[selectedWeekday].labelKey as TranslationKey),
          time 
        });
      case "monthly":
        return t("recurrencePreviewMonthly" as TranslationKey, { day: selectedMonthday, time });
      case "yearly":
        return t("recurrencePreviewYearly" as TranslationKey, { 
          month: t(MONTHS[selectedMonth - 1].labelKey as TranslationKey),
          day: selectedYearDay,
          time 
        });
      default:
        return "";
    }
  };

  const modes: { value: RecurrenceMode; labelKey: string }[] = [
    { value: "daily", labelKey: "modeDaily" },
    { value: "weekly", labelKey: "modeWeekly" },
    { value: "biweekly", labelKey: "modeBiweekly" },
    { value: "monthly", labelKey: "modeMonthly" },
    { value: "yearly", labelKey: "modeYearly" },
  ];

  return (
    <div className={cn("space-y-4", className)}>
      {/* Mode Selector - Segmented Control */}
      <div className="flex rounded-lg bg-slate-100/80 p-1">
        {modes.map((m) => (
          <button
            key={m.value}
            type="button"
            onClick={() => handleModeChange(m.value)}
            className={cn(
              "flex-1 rounded-md px-2 py-1.5 text-xs font-medium transition-all",
              mode === m.value
                ? "bg-white text-slate-900 shadow-sm"
                : "text-slate-600 hover:text-slate-900"
            )}
          >
            {t(m.labelKey as TranslationKey)}
          </button>
        ))}
      </div>

      {/* Mode-specific Options */}
      <div className="min-h-[60px]">
        {/* Weekly / Biweekly - Weekday Selector */}
        {(mode === "weekly" || mode === "biweekly") && (
          <div className="space-y-2">
            <label className="text-xs font-medium text-slate-500">
              {t("selectWeekday")}
            </label>
            <div className="flex gap-1.5">
              {WEEKDAYS.map((day) => (
                <button
                  key={day.value}
                  type="button"
                  onClick={() => handleWeekdayChange(day.value)}
                  className={cn(
                    "flex h-8 w-8 items-center justify-center rounded-full text-xs font-medium transition-all",
                    selectedWeekday === day.value
                      ? "bg-blue-500 text-white shadow-sm"
                      : "bg-slate-100 text-slate-600 hover:bg-slate-200"
                  )}
                >
                  {t(day.labelKey as TranslationKey)}
                </button>
              ))}
            </div>
          </div>
        )}

        {/* Monthly - Day of Month Selector */}
        {mode === "monthly" && (
          <div className="space-y-2">
            <label className="text-xs font-medium text-slate-500">
              {t("selectMonthday")}
            </label>
            <div className="flex items-center gap-2">
              <span className="text-sm text-slate-600">{t("everyMonth")}</span>
              <select
                value={selectedMonthday}
                onChange={(e) => handleMonthdayChange(Number(e.target.value))}
                className="h-9 rounded-lg border border-slate-200/60 bg-white px-3 text-sm focus:outline-none focus:ring-2 focus:ring-primary/30"
              >
                {Array.from({ length: 31 }, (_, i) => i + 1).map((day) => (
                  <option key={day} value={day}>
                    {day}
                  </option>
                ))}
              </select>
              <span className="text-sm text-slate-600">{t("dayUnit")}</span>
            </div>
          </div>
        )}

        {/* Yearly - Month and Day Selector */}
        {mode === "yearly" && (
          <div className="space-y-2">
            <label className="text-xs font-medium text-slate-500">
              {t("selectYearlyDate")}
            </label>
            <div className="flex items-center gap-2">
              <span className="text-sm text-slate-600">{t("everyYear")}</span>
              <select
                value={selectedMonth}
                onChange={(e) => handleMonthChange(Number(e.target.value))}
                className="h-9 rounded-lg border border-slate-200/60 bg-white px-3 text-sm focus:outline-none focus:ring-2 focus:ring-primary/30"
              >
                {MONTHS.map((month) => (
                  <option key={month.value} value={month.value}>
                    {t(month.labelKey as TranslationKey)}
                  </option>
                ))}
              </select>
              <select
                value={selectedYearDay}
                onChange={(e) => handleYearDayChange(Number(e.target.value))}
                className="h-9 rounded-lg border border-slate-200/60 bg-white px-3 text-sm focus:outline-none focus:ring-2 focus:ring-primary/30"
              >
                {Array.from({ length: getDaysInMonth(selectedMonth) }, (_, i) => i + 1).map((day) => (
                  <option key={day} value={day}>
                    {day}
                  </option>
                ))}
              </select>
              <span className="text-sm text-slate-600">{t("dayUnit")}</span>
            </div>
          </div>
        )}

        {/* Daily - No additional options needed */}
        {mode === "daily" && (
          <div className="flex items-center justify-center py-2 text-sm text-slate-500">
            {t("dailyNoOptions")}
          </div>
        )}
      </div>

      {/* Preview */}
      <div className="rounded-lg bg-blue-50 px-3 py-2">
        <div className="flex items-center gap-2">
          <span className="text-xs font-medium text-blue-600/70">{t("willRepeat")}</span>
          <span className="text-sm font-medium text-blue-600">{getPreviewText()}</span>
        </div>
      </div>
    </div>
  );
}
