"use client";

import { useEffect, useState, type FormEvent } from "react";

import { getCategoryLabel, type CategoryValue } from "@/lib/categories";
import { formatCurrencyFromCents } from "@/lib/money";

type RecurringDefinition = {
  id: string;
  title: string;
  amountCents: number;
  category: string;
  dayOfMonth: number;
};

type CategoryOption = {
  value: string;
  label: string;
};

type Props = {
  categoryOptions: CategoryOption[];
};

const emptyForm = { title: "", amount: "", dayOfMonth: "1", category: "MISC" as CategoryValue };

export function RecurringExpenseManager({ categoryOptions }: Props) {
  const [definitions, setDefinitions] = useState<RecurringDefinition[]>([]);
  const [showAddForm, setShowAddForm] = useState(false);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [formState, setFormState] = useState(emptyForm);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    async function load() {
      const res = await fetch("/recurring-expenses", { cache: "no-store" });
      const payload = (await res.json()) as { recurringExpenses?: RecurringDefinition[] };
      setDefinitions(payload.recurringExpenses ?? []);
    }
    void load();
  }, []);

  function openAdd() {
    setEditingId(null);
    setFormState(emptyForm);
    setError(null);
    setShowAddForm(true);
  }

  function openEdit(def: RecurringDefinition) {
    setShowAddForm(false);
    setEditingId(def.id);
    setFormState({
      title: def.title,
      amount: (def.amountCents / 100).toFixed(2),
      dayOfMonth: String(def.dayOfMonth),
      category: def.category as CategoryValue,
    });
    setError(null);
  }

  function cancelForm() {
    setShowAddForm(false);
    setEditingId(null);
    setFormState(emptyForm);
    setError(null);
  }

  async function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setBusy(true);
    setError(null);

    const isEditing = editingId !== null;
    const url = isEditing ? `/recurring-expenses/${editingId}` : "/recurring-expenses";
    const response = await fetch(url, {
      method: isEditing ? "PATCH" : "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        title: formState.title,
        amount: formState.amount,
        dayOfMonth: parseInt(formState.dayOfMonth, 10),
        category: formState.category,
      }),
    });

    setBusy(false);

    if (!response.ok) {
      const payload = (await response.json().catch(() => null)) as { error?: string } | null;
      setError(payload?.error ?? "Could not save.");
      return;
    }

    const payload = (await response.json()) as { recurringExpense: RecurringDefinition };

    if (isEditing) {
      setDefinitions((current) =>
        current.map((d) => (d.id === editingId ? payload.recurringExpense : d)),
      );
    } else {
      setDefinitions((current) => [...current, payload.recurringExpense]);
    }

    cancelForm();
  }

  async function handleDelete(id: string) {
    setBusy(true);
    const response = await fetch(`/recurring-expenses/${id}`, { method: "DELETE" });
    setBusy(false);

    if (!response.ok) {
      setError("Could not delete.");
      return;
    }

    setDefinitions((current) => current.filter((d) => d.id !== id));
  }

  return (
    <section className="rounded-[2rem] border border-amber-200 bg-amber-50 p-6 shadow-[0_24px_60px_rgba(120,90,50,0.08)] dark:border-amber-900/40 dark:bg-amber-900/10">
      <div className="mb-5 flex items-center justify-between gap-4">
        <div>
          <p className="text-sm font-semibold uppercase tracking-[0.24em] text-amber-700 dark:text-amber-400">Fixed monthly costs</p>
          <h2 className="mt-2 text-2xl font-semibold text-stone-950 dark:text-white">Recurring expenses</h2>
          <p className="mt-1 text-sm text-stone-600 dark:text-stone-400">These appear automatically in every month without manual entry.</p>
        </div>
        {!showAddForm && editingId === null && (
          <button
            type="button"
            onClick={openAdd}
            className="shrink-0 rounded-full bg-stone-950 px-4 py-2.5 text-sm font-semibold text-white transition hover:bg-stone-700 dark:bg-stone-100 dark:text-stone-900 dark:hover:bg-white"
          >
            + Add recurring
          </button>
        )}
      </div>

      {(showAddForm || editingId !== null) && (
        <form
          onSubmit={handleSubmit}
          className="mb-5 grid gap-3 rounded-2xl border border-amber-200 bg-white p-5 md:grid-cols-2 dark:border-amber-900/40 dark:bg-stone-900"
        >
          <p className="text-sm font-semibold text-stone-700 dark:text-stone-300 md:col-span-2">
            {editingId ? "Edit recurring expense" : "New recurring expense"}
          </p>

          <label className="grid gap-1.5 text-sm font-medium text-stone-700 dark:text-stone-300 md:col-span-2">
            Title
            <input
              required
              value={formState.title}
              onChange={(e) => setFormState((s) => ({ ...s, title: e.target.value }))}
              className="rounded-2xl border border-stone-300 bg-stone-50 px-4 py-2.5 outline-none transition focus:border-stone-900 dark:border-stone-600 dark:bg-stone-800 dark:text-stone-200 dark:focus:border-stone-400"
              placeholder="Rent, car insurance, EMI..."
            />
          </label>

          <label className="grid gap-1.5 text-sm font-medium text-stone-700 dark:text-stone-300">
            Amount
            <input
              required
              inputMode="decimal"
              value={formState.amount}
              onChange={(e) => setFormState((s) => ({ ...s, amount: e.target.value }))}
              className="rounded-2xl border border-stone-300 bg-stone-50 px-4 py-2.5 outline-none transition focus:border-stone-900 dark:border-stone-600 dark:bg-stone-800 dark:text-stone-200 dark:focus:border-stone-400"
              placeholder="1200.00"
            />
          </label>

          <label className="grid gap-1.5 text-sm font-medium text-stone-700 dark:text-stone-300">
            Day of month
            <input
              required
              type="number"
              min={1}
              max={28}
              value={formState.dayOfMonth}
              onChange={(e) => setFormState((s) => ({ ...s, dayOfMonth: e.target.value }))}
              className="rounded-2xl border border-stone-300 bg-stone-50 px-4 py-2.5 outline-none transition focus:border-stone-900 dark:border-stone-600 dark:bg-stone-800 dark:text-stone-200 dark:focus:border-stone-400"
              placeholder="1"
            />
          </label>

          <label className="grid gap-1.5 text-sm font-medium text-stone-700 dark:text-stone-300 md:col-span-2">
            Category
            <select
              value={formState.category}
              onChange={(e) => setFormState((s) => ({ ...s, category: e.target.value as CategoryValue }))}
              className="rounded-2xl border border-stone-300 bg-stone-50 px-4 py-2.5 outline-none transition focus:border-stone-900 dark:border-stone-600 dark:bg-stone-800 dark:text-stone-200 dark:focus:border-stone-400"
            >
              {categoryOptions.map((option) => (
                <option key={option.value} value={option.value}>
                  {option.label}
                </option>
              ))}
            </select>
          </label>

          <div className="md:col-span-2 flex items-center justify-between gap-3">
            <p className="text-sm text-rose-700">{error}</p>
            <div className="flex gap-2">
              <button
                type="button"
                onClick={cancelForm}
                className="rounded-full border border-stone-300 px-4 py-2.5 text-sm font-semibold text-stone-700 transition hover:border-stone-900 dark:border-stone-600 dark:text-stone-300 dark:hover:border-stone-300"
              >
                Cancel
              </button>
              <button
                type="submit"
                disabled={busy}
                className="rounded-full bg-stone-950 px-4 py-2.5 text-sm font-semibold text-white transition hover:bg-stone-800 disabled:cursor-not-allowed disabled:bg-stone-400 dark:bg-stone-100 dark:text-stone-900 dark:hover:bg-white dark:disabled:bg-stone-700 dark:disabled:text-stone-500"
              >
                {busy ? "Saving..." : editingId ? "Update" : "Save"}
              </button>
            </div>
          </div>
        </form>
      )}

      {!showAddForm && editingId === null && error && (
        <p className="mb-3 text-sm text-rose-700">{error}</p>
      )}

      {definitions.length === 0 && !showAddForm ? (
        <div className="rounded-3xl border border-dashed border-amber-300 px-4 py-6 text-sm text-stone-600 dark:border-amber-800/50 dark:text-stone-400">
          No recurring expenses yet. Add fixed monthly costs like rent or EMI.
        </div>
      ) : (
        <div className="space-y-2">
          {definitions.map((def) => (
            <article
              key={def.id}
              className={`flex items-center justify-between gap-4 rounded-3xl border px-4 py-4 ${
                editingId === def.id
                  ? "border-amber-300 bg-amber-100/50 dark:border-amber-700/50 dark:bg-amber-900/20"
                  : "border-amber-200 bg-white dark:border-amber-900/30 dark:bg-stone-900"
              }`}
            >
              <div>
                <p className="font-semibold text-stone-950 dark:text-white">{def.title}</p>
                <p className="mt-1 text-sm text-stone-600 dark:text-stone-400">
                  Day {def.dayOfMonth} each month · {getCategoryLabel(def.category as CategoryValue)}
                </p>
              </div>
              <div className="flex items-center gap-2">
                <p className="mr-2 font-semibold text-stone-950 dark:text-white">{formatCurrencyFromCents(def.amountCents)}</p>
                {editingId !== def.id && (
                  <>
                    <button
                      type="button"
                      onClick={() => openEdit(def)}
                      className="rounded-full border border-stone-300 px-3 py-2 text-xs font-semibold uppercase tracking-[0.2em] text-stone-600 transition hover:border-stone-900 hover:text-stone-900 dark:border-stone-600 dark:text-stone-400 dark:hover:border-stone-300 dark:hover:text-stone-200"
                    >
                      Edit
                    </button>
                    <button
                      type="button"
                      disabled={busy}
                      onClick={() => void handleDelete(def.id)}
                      className="rounded-full border border-stone-300 px-3 py-2 text-xs font-semibold uppercase tracking-[0.2em] text-stone-600 transition hover:border-rose-400 hover:text-rose-600 disabled:cursor-not-allowed dark:border-stone-600 dark:text-stone-400 dark:hover:border-rose-500 dark:hover:text-rose-400"
                    >
                      Delete
                    </button>
                  </>
                )}
              </div>
            </article>
          ))}
        </div>
      )}
    </section>
  );
}
