"use client";

import { useEffect, useState, type FormEvent } from "react";
import { JalaliDatePicker } from "@/components/jalali-date-picker/jalali-date-picker";
import { getTodayGregorianIso } from "@/components/jalali-date-picker/utils";
import { Select } from "@/components/select";
import { habitsDict } from "@/features/habits/dict";
import type { Habit, HabitLog, HabitLogFormValues, HabitLogStatus } from "@/features/habits/types";
import {
  defaultLogFormValues,
  formatLogLocalDate,
  logFormToPayload,
  logFormToUpdatePayload,
  logToFormValues,
  shouldShowLogValue,
  validateLogForm,
} from "@/features/habits/utils/habit-helpers";

type HabitLogSheetProps = {
  open: boolean;
  mode: "create" | "edit";
  habit: Habit | null;
  log?: HabitLog | null;
  existingLogs?: HabitLog[];
  initialLocalDate?: string;
  lockLocalDate?: boolean;
  isSubmitting: boolean;
  onClose: () => void;
  onSubmit: (
    payload: ReturnType<typeof logFormToPayload> | ReturnType<typeof logFormToUpdatePayload>,
  ) => void;
};

const statusOptions = Object.keys(habitsDict.logStatuses) as HabitLogStatus[];

export function HabitLogSheet({
  open,
  mode,
  habit,
  log,
  existingLogs = [],
  initialLocalDate,
  lockLocalDate = false,
  isSubmitting,
  onClose,
  onSubmit,
}: HabitLogSheetProps) {
  const [values, setValues] = useState<HabitLogFormValues>({
    localDate: "",
    status: "COMPLETED",
    value: "",
    note: "",
  });
  const [errors, setErrors] = useState<Partial<Record<keyof HabitLogFormValues, string>>>({});

  useEffect(() => {
    if (!open || !habit) return;

    if (mode === "edit" && log) {
      setValues(logToFormValues(log));
    } else {
      setValues(defaultLogFormValues(habit, initialLocalDate));
    }

    setErrors({});
  }, [open, mode, habit, log, initialLocalDate]);

  useEffect(() => {
    if (!open) return;

    const handleEscape = (event: KeyboardEvent) => {
      if (event.key === "Escape") onClose();
    };

    document.addEventListener("keydown", handleEscape);
    document.body.style.overflow = "hidden";

    return () => {
      document.removeEventListener("keydown", handleEscape);
      document.body.style.overflow = "";
    };
  }, [open, onClose]);

  if (!open || !habit) return null;

  const showValue = shouldShowLogValue(habit);
  const valueLabel = habit.unit
    ? `${habitsDict.logValueLabel} (${habit.unit})`
    : habitsDict.logValueLabel;

  const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    const nextErrors = validateLogForm(values, habit, {
      existingLogs,
      editingLogId: mode === "edit" ? log?.id : undefined,
    });

    if (Object.keys(nextErrors).length > 0) {
      setErrors(nextErrors);
      return;
    }

    onSubmit(
      mode === "edit" && log
        ? logFormToUpdatePayload(values, log)
        : logFormToPayload(values),
    );
  };

  return (
    <div className="fixed inset-0 z-[100] flex items-end justify-center bg-black/40 p-0 sm:items-center sm:p-4">
      <button type="button" aria-label={habitsDict.cancel} className="absolute inset-0" onClick={onClose} />

      <div className="relative z-10 flex max-h-[96vh] w-full max-w-lg flex-col overflow-hidden rounded-t-3xl bg-card shadow-soft sm:rounded-3xl">
        <div className="shrink-0 px-6 pt-4">
          <div className="mx-auto mb-4 h-1.5 w-12 rounded-full bg-border sm:hidden" />
          <div className="space-y-1 pb-4 text-center sm:text-start">
            <h2 className="text-xl font-bold text-card-foreground">
              {mode === "create" ? habitsDict.logTitle : habitsDict.editLog}
            </h2>
            <p className="text-sm text-muted-foreground">{habit.name}</p>
          </div>
        </div>

        <form onSubmit={handleSubmit} className="flex min-h-0 flex-1 flex-col">
          <div className="min-h-0 flex-1 space-y-4 overflow-y-auto px-6 pb-4">
            <div className="space-y-2">
              <label htmlFor="habit-log-date" className="text-sm font-medium">
                {habitsDict.logDateLabel}
              </label>
              {lockLocalDate ? (
                <div className="flex h-12 items-center rounded-2xl bg-input px-4 text-sm shadow-soft-sm ring-1 ring-border">
                  {formatLogLocalDate(values.localDate)}
                </div>
              ) : (
                <JalaliDatePicker
                  id="habit-log-date"
                  value={values.localDate}
                  maxDate={getTodayGregorianIso()}
                  onChange={(localDate) =>
                    setValues((current) => ({ ...current, localDate }))
                  }
                />
              )}
              {errors.localDate ? (
                <p className="text-sm text-destructive">{errors.localDate}</p>
              ) : null}
            </div>

            <div className="space-y-2">
              <label htmlFor="habit-log-status" className="text-sm font-medium">
                {habitsDict.logStatusLabel}
              </label>
              <Select
                id="habit-log-status"
                value={values.status}
                onChange={(e) =>
                  setValues((current) => ({
                    ...current,
                    status: e.target.value as HabitLogStatus,
                  }))
                }
              >
                {statusOptions.map((option) => (
                  <option key={option} value={option}>
                    {habitsDict.logStatuses[option]}
                  </option>
                ))}
              </Select>
            </div>

            {showValue ? (
              <div className="space-y-2">
                <label htmlFor="habit-log-value" className="text-sm font-medium">
                  {valueLabel}
                </label>
                <input
                  id="habit-log-value"
                  type="number"
                  min={0}
                  step={1}
                  dir="ltr"
                  value={values.value}
                  onChange={(e) =>
                    setValues((current) => ({ ...current, value: e.target.value }))
                  }
                  placeholder={habitsDict.logValuePlaceholder}
                  className="h-12 w-full rounded-2xl bg-input px-4 text-sm shadow-soft-sm ring-1 ring-border outline-none focus:ring-2 focus:ring-primary"
                />
                {errors.value ? (
                  <p className="text-sm text-destructive">{errors.value}</p>
                ) : null}
              </div>
            ) : null}

            <div className="space-y-2">
              <label htmlFor="habit-log-note" className="text-sm font-medium">
                {habitsDict.logNoteLabel}
              </label>
              <textarea
                id="habit-log-note"
                value={values.note}
                onChange={(e) =>
                  setValues((current) => ({ ...current, note: e.target.value }))
                }
                placeholder={habitsDict.logNotePlaceholder}
                rows={3}
                className="w-full rounded-2xl bg-input px-4 py-3 text-sm shadow-soft-sm ring-1 ring-border outline-none focus:ring-2 focus:ring-primary"
              />
            </div>
          </div>

          <div className="shrink-0 border-t border-border bg-card px-6 py-4">
            <div className="flex flex-row gap-3">
              <button
                type="submit"
                disabled={isSubmitting}
                className="inline-flex h-12 flex-1 items-center justify-center rounded-2xl bg-primary text-primary-foreground shadow-soft-sm transition-all hover:brightness-105 disabled:opacity-60"
              >
                {isSubmitting
                  ? habitsDict.saving
                  : mode === "create"
                    ? habitsDict.logReport
                    : habitsDict.save}
              </button>

              <button
                type="button"
                onClick={onClose}
                className="inline-flex h-12 flex-1 items-center justify-center rounded-2xl border border-border bg-background text-foreground transition-colors hover:bg-accent"
              >
                {habitsDict.cancel}
              </button>
            </div>
          </div>
        </form>
      </div>
    </div>
  );
}
