"use client";

import { useEffect, useState, type FormEvent } from "react";
import { JalaliDatePicker } from "@/components/jalali-date-picker/jalali-date-picker";
import { Select } from "@/components/select";
import { CategoryPicker } from "@/features/categories/components/category-picker";
import type { Habit } from "@/features/habits/types";
import type { Task } from "@/features/tasks/types";
import { GoalSourcesEditor } from "@/features/goals/components/goal-sources-editor";
import { goalsDict } from "@/features/goals/dict";
import type {
  Goal,
  GoalFormValues,
  GoalMissPolicy,
  GoalStatus,
  GoalTargetOperator,
  GoalValueType,
} from "@/features/goals/types";
import {
  getDefaultGoalFormValues,
  goalToFormValues,
  validateGoalForm,
} from "@/features/goals/utils/goal-helpers";
import { DESCRIPTION_MAX_LENGTH, TITLE_MAX_LENGTH } from "@/lib/field-limits";

type GoalSheetProps = {
  open: boolean;
  mode: "create" | "edit";
  goal?: Goal | null;
  habits: Habit[];
  tasks: Task[];
  isSubmitting: boolean;
  isDeleting?: boolean;
  onClose: () => void;
  onSubmit: (values: GoalFormValues) => void;
  onDelete?: () => void;
};

const valueTypeOptions = Object.keys(goalsDict.valueTypes) as GoalValueType[];
const operatorOptions = Object.keys(goalsDict.targetOperators) as GoalTargetOperator[];
const statusOptions = Object.keys(goalsDict.statuses) as GoalStatus[];
const missPolicyOptions = (
  Object.keys(goalsDict.missPolicies) as GoalMissPolicy[]
).filter((option) => option !== "CHAIN");

export function GoalSheet({
  open,
  mode,
  goal,
  habits,
  tasks,
  isSubmitting,
  isDeleting = false,
  onClose,
  onSubmit,
  onDelete,
}: GoalSheetProps) {
  const [values, setValues] = useState<GoalFormValues>(() =>
    getDefaultGoalFormValues(),
  );
  const [errors, setErrors] = useState<Partial<Record<keyof GoalFormValues, string>>>({});

  useEffect(() => {
    if (!open) return;

    if (mode === "edit" && goal) {
      setValues(goalToFormValues(goal));
    } else {
      setValues(getDefaultGoalFormValues());
    }

    setErrors({});
  }, [open, mode, goal]);

  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) return null;

  const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    const nextErrors = validateGoalForm(values);

    if (Object.keys(nextErrors).length > 0) {
      setErrors(nextErrors);
      return;
    }

    onSubmit(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={goalsDict.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" ? goalsDict.addGoal : goalsDict.editGoal}
            </h2>
            <p className="text-sm text-muted-foreground">{goalsDict.subtitle}</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="goal-title" className="text-sm font-medium">{goalsDict.titleLabel}</label>
              <input
                id="goal-title"
                value={values.title}
                maxLength={TITLE_MAX_LENGTH}
                onChange={(e) => setValues((c) => ({ ...c, title: e.target.value }))}
                placeholder={goalsDict.titlePlaceholder}
                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.title ? <p className="text-sm text-destructive">{errors.title}</p> : null}
            </div>

            <div className="space-y-2">
              <label htmlFor="goal-description" className="text-sm font-medium">{goalsDict.descriptionLabel}</label>
              <textarea
                id="goal-description"
                value={values.description}
                maxLength={DESCRIPTION_MAX_LENGTH}
                onChange={(e) => setValues((c) => ({ ...c, description: e.target.value }))}
                placeholder={goalsDict.descriptionPlaceholder}
                rows={2}
                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"
              />
              {errors.description ? (
                <p className="text-sm text-destructive">{errors.description}</p>
              ) : null}
            </div>

            <div className="space-y-2">
              <CategoryPicker
                domain="GOAL"
                value={values.category}
                onChange={(category) => setValues((c) => ({ ...c, category }))}
                id="goal-category"
                label={goalsDict.goalTypeLabel}
              />
            </div>

            <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
              <div className="space-y-2">
                <label htmlFor="goal-value-type" className="text-sm font-medium">{goalsDict.valueTypeLabel}</label>
                <Select
                  id="goal-value-type"
                  value={values.valueType}
                  onChange={(e) => setValues((c) => ({ ...c, valueType: e.target.value as GoalValueType }))}
                >
                  {valueTypeOptions.map((option) => (
                    <option key={option} value={option}>{goalsDict.valueTypes[option]}</option>
                  ))}
                </Select>
              </div>

              <div className="space-y-2">
                <label htmlFor="goal-unit" className="text-sm font-medium">{goalsDict.unitLabel}</label>
                <input
                  id="goal-unit"
                  value={values.unit}
                  onChange={(e) => setValues((c) => ({ ...c, unit: e.target.value }))}
                  placeholder={goalsDict.unitPlaceholder}
                  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"
                />
              </div>
            </div>

            <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
              <div className="space-y-2">
                <label htmlFor="goal-operator" className="text-sm font-medium">{goalsDict.targetOperatorLabel}</label>
                <Select
                  id="goal-operator"
                  value={values.targetOperator}
                  onChange={(e) => setValues((c) => ({ ...c, targetOperator: e.target.value as GoalTargetOperator }))}
                >
                  {operatorOptions.map((option) => (
                    <option key={option} value={option}>{goalsDict.targetOperators[option]}</option>
                  ))}
                </Select>
              </div>

              <div className="space-y-2">
                <label htmlFor="goal-target-value" className="text-sm font-medium">{goalsDict.targetValueLabel}</label>
                <input
                  id="goal-target-value"
                  type="number"
                  min={0}
                  dir="ltr"
                  value={values.targetValue}
                  onChange={(e) => setValues((c) => ({ ...c, targetValue: e.target.value }))}
                  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.targetValue ? <p className="text-sm text-destructive">{errors.targetValue}</p> : null}
              </div>
            </div>

            <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
              <div className="space-y-2">
                <label htmlFor="goal-start-date" className="text-sm font-medium">{goalsDict.startDateLabel}</label>
                <JalaliDatePicker
                  id="goal-start-date"
                  value={values.startDate}
                  onChange={(startDate) => setValues((c) => ({ ...c, startDate }))}
                />
                {errors.startDate ? <p className="text-sm text-destructive">{errors.startDate}</p> : null}
              </div>

              <div className="space-y-2">
                <label htmlFor="goal-end-date" className="text-sm font-medium">{goalsDict.endDateLabel}</label>
                <JalaliDatePicker
                  id="goal-end-date"
                  value={values.endDate}
                  onChange={(endDate) => setValues((c) => ({ ...c, endDate }))}
                  clearable
                />
              </div>
            </div>

            <div className="space-y-2">
              <label htmlFor="goal-miss-policy" className="text-sm font-medium">{goalsDict.missPolicyLabel}</label>
              <Select
                id="goal-miss-policy"
                value={values.missPolicy}
                onChange={(e) => setValues((c) => ({ ...c, missPolicy: e.target.value as GoalMissPolicy }))}
              >
                {missPolicyOptions.map((option) => (
                  <option key={option} value={option}>{goalsDict.missPolicies[option]}</option>
                ))}
              </Select>
            </div>

            <div className="space-y-2">
              <label htmlFor="goal-status" className="text-sm font-medium">{goalsDict.statusLabel}</label>
              <Select
                id="goal-status"
                value={values.status}
                onChange={(e) => setValues((c) => ({ ...c, status: e.target.value as GoalStatus }))}
              >
                {statusOptions.map((option) => (
                  <option key={option} value={option}>{goalsDict.statuses[option]}</option>
                ))}
              </Select>
            </div>

            <GoalSourcesEditor
              sources={values.sources}
              habits={habits}
              tasks={tasks}
              onChange={(sources) => setValues((c) => ({ ...c, sources }))}
            />
            {errors.sources ? <p className="text-sm text-destructive">{errors.sources}</p> : null}
          </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 || isDeleting}
                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 ? goalsDict.saving : goalsDict.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"
              >
                {goalsDict.cancel}
              </button>

              {mode === "edit" && onDelete ? (
                <button
                  type="button"
                  onClick={onDelete}
                  disabled={isDeleting || isSubmitting}
                  className="inline-flex h-12 flex-1 items-center justify-center rounded-2xl border border-destructive/30 text-destructive transition-colors hover:bg-destructive/10 disabled:opacity-60"
                >
                  {goalsDict.delete}
                </button>
              ) : null}
            </div>
          </div>
        </form>
      </div>
    </div>
  );
}
