import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { Button } from "@/components/ui/button";
import type { PeriodicExpense } from "@/lib/api";

const months = [
  { value: 1, label: "Ene" },
  { value: 2, label: "Feb" },
  { value: 3, label: "Mar" },
  { value: 4, label: "Abr" },
  { value: 5, label: "May" },
  { value: 6, label: "Jun" },
  { value: 7, label: "Jul" },
  { value: 8, label: "Ago" },
  { value: 9, label: "Sep" },
  { value: 10, label: "Oct" },
  { value: 11, label: "Nov" },
  { value: 12, label: "Dic" },
];

const periodicExpenseFormSchema = z.object({
  description: z
    .string()
    .min(1, "La descripción es obligatoria")
    .max(50, "Máximo 50 caracteres"),
  defaultDueDay: z
    .number()
    .int()
    .min(1, "Día entre 1 y 31")
    .max(31, "Día entre 1 y 31"),
  defaultAmount: z.number().positive("El monto debe ser mayor a 0"),
  periods: z.array(z.number()).min(1, "Seleccioná al menos un mes"),
});

type PeriodicExpenseFormValues = z.infer<typeof periodicExpenseFormSchema>;

interface PeriodicExpenseFormProps {
  initialData?: PeriodicExpense;
  onSubmit: (data: PeriodicExpenseFormValues) => Promise<void>;
  onCancel: () => void;
}

export function PeriodicExpenseForm({
  initialData,
  onSubmit,
  onCancel,
}: PeriodicExpenseFormProps) {
  const {
    register,
    handleSubmit,
    watch,
    setValue,
    formState: { errors, isSubmitting },
  } = useForm<PeriodicExpenseFormValues>({
    resolver: zodResolver(periodicExpenseFormSchema),
    defaultValues: initialData
      ? {
          description: initialData.description,
          defaultDueDay: initialData.defaultDueDay,
          defaultAmount: Number(initialData.defaultAmount),
          periods: initialData.periods,
        }
      : {
          description: "",
          defaultDueDay: 15,
          defaultAmount: 0,
          periods: [],
        },
  });

  const selectedPeriods = watch("periods");

  function toggleMonth(month: number) {
    if (selectedPeriods.includes(month)) {
      setValue(
        "periods",
        selectedPeriods.filter((m) => m !== month),
        { shouldValidate: true },
      );
    } else {
      setValue("periods", [...selectedPeriods, month], {
        shouldValidate: true,
      });
    }
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="flex flex-col gap-4">
      <div className="flex flex-col gap-1.5">
        <label htmlFor="description" className="text-sm font-medium">
          Descripción
        </label>
        <input
          id="description"
          {...register("description")}
          placeholder="Ej: Gimnasio"
          className="h-8 rounded-lg border border-input bg-background px-2.5 text-sm outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50"
        />
        {errors.description && (
          <span className="text-xs text-destructive">
            {errors.description.message}
          </span>
        )}
      </div>

      <div className="flex gap-3">
        <div className="flex flex-1 flex-col gap-1.5">
          <label htmlFor="defaultAmount" className="text-sm font-medium">
            Monto
          </label>
          <input
            id="defaultAmount"
            type="number"
            step="0.01"
            min="0"
            {...register("defaultAmount", { valueAsNumber: true })}
            placeholder="1500"
            className="h-8 rounded-lg border border-input bg-background px-2.5 text-sm outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50"
          />
          {errors.defaultAmount && (
            <span className="text-xs text-destructive">
              {errors.defaultAmount.message}
            </span>
          )}
        </div>

        <div className="flex flex-1 flex-col gap-1.5">
          <label htmlFor="defaultDueDay" className="text-sm font-medium">
            Día de vencimiento
          </label>
          <input
            id="defaultDueDay"
            type="number"
            min="1"
            max="31"
            {...register("defaultDueDay", { valueAsNumber: true })}
            className="h-8 rounded-lg border border-input bg-background px-2.5 text-sm outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50"
          />
          {errors.defaultDueDay && (
            <span className="text-xs text-destructive">
              {errors.defaultDueDay.message}
            </span>
          )}
        </div>
      </div>

      <div className="flex flex-col gap-1.5">
        <div className="flex items-center justify-between">
          <span className="text-sm font-medium">Meses de aplicación</span>
          <div className="flex gap-2">
            <button
              type="button"
              onClick={() => {
                const all = months.map((m) => m.value);
                setValue("periods", all, { shouldValidate: true });
              }}
              className="text-xs text-muted-foreground underline underline-offset-2 hover:text-foreground"
            >
              Seleccionar todos
            </button>
            <button
              type="button"
              onClick={() => setValue("periods", [], { shouldValidate: true })}
              className="text-xs text-muted-foreground underline underline-offset-2 hover:text-foreground"
            >
              Deseleccionar todos
            </button>
          </div>
        </div>
        <div className="flex flex-wrap gap-1.5">
          {months.map((m) => (
            <button
              key={m.value}
              type="button"
              onClick={() => toggleMonth(m.value)}
              className={
                selectedPeriods.includes(m.value)
                  ? "h-7 rounded-md bg-primary px-2.5 text-xs font-medium text-primary-foreground transition-colors"
                  : "h-7 rounded-md border border-input bg-background px-2.5 text-xs font-medium text-muted-foreground transition-colors hover:bg-muted"
              }
            >
              {m.label}
            </button>
          ))}
        </div>
        {errors.periods && (
          <span className="text-xs text-destructive">
            {errors.periods.message}
          </span>
        )}
        <input type="hidden" {...register("periods")} />
      </div>

      <div className="flex flex-col-reverse sm:flex-row sm:justify-end gap-2 mt-2">
        <Button
          type="button"
          variant="outline"
          onClick={onCancel}
          disabled={isSubmitting}
        >
          Cancelar
        </Button>
        <Button type="submit" disabled={isSubmitting}>
          {initialData ? "Guardar cambios" : "Crear gasto periódico"}
        </Button>
      </div>
    </form>
  );
}
