"use client";

import { useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Plus, PiggyBank, Trash2, AlertTriangle } from "lucide-react";
import { createClient } from "@/lib/supabase/client";
import { Card } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input, Label, Select, FieldError } from "@/components/ui/input";
import { Modal } from "@/components/ui/modal";
import { Progress } from "@/components/ui/progress";
import { EmptyState } from "@/components/shared/empty-state";
import { budgetCategorySchema, type BudgetCategoryInput } from "@/lib/validation/schemas";
import { useTranslations, useLocale } from "@/lib/i18n/i18n-provider";
import { formatMoney, clampPercent } from "@/lib/utils";
import { PLANS, type PlanId } from "@/lib/pricing";
import type { BudgetCategory, Currency } from "@/types/database";

const CATEGORIES = [
  "food",
  "housing",
  "transport",
  "shopping",
  "entertainment",
  "health",
  "bills",
  "subscriptions",
  "travel",
  "education",
  "other"
] as const;

export function BudgetView({
  budgetId,
  initialCategories,
  spentByCategory,
  currency,
  plan
}: {
  budgetId: string;
  initialCategories: BudgetCategory[];
  spentByCategory: Record<string, number>;
  currency: Currency;
  plan: PlanId;
}) {
  const t = useTranslations();
  const locale = useLocale();
  const [categories, setCategories] = useState(initialCategories);
  const [modalOpen, setModalOpen] = useState(false);

  const limit = PLANS[plan].limits.maxBudgetCategories;
  const atLimit = limit !== null && categories.length >= limit;

  async function handleDelete(id: string) {
    const supabase = createClient();
    const prev = categories;
    setCategories((c) => c.filter((x) => x.id !== id));
    const { error } = await supabase.from("budget_categories").delete().eq("id", id);
    if (error) setCategories(prev);
  }

  return (
    <div className="space-y-4">
      <div className="flex justify-end">
        <Button onClick={() => setModalOpen(true)} disabled={atLimit || !budgetId}>
          <Plus className="h-4 w-4" /> {t("budget.add")}
        </Button>
      </div>

      {categories.length === 0 ? (
        <EmptyState title={t("budget.empty.title")} cta={t("budget.empty.cta")} onCta={() => setModalOpen(true)} icon={PiggyBank} />
      ) : (
        <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
          {categories.map((c) => {
            const spent = spentByCategory[c.category] ?? 0;
            const pct = clampPercent((spent / Number(c.amount || 1)) * 100);
            const remaining = Number(c.amount) - spent;
            const tone = pct >= 100 ? "danger" : pct >= 80 ? "warning" : "brand";

            return (
              <Card key={c.id}>
                <div className="mb-2 flex items-start justify-between">
                  <h3 className="text-sm font-semibold text-ink-900">{t(`expenses.categories.${c.category}`)}</h3>
                  <button
                    onClick={() => handleDelete(c.id)}
                    aria-label={t("common.delete")}
                    className="rounded-lg p-1 text-ink-300 hover:bg-red-50 hover:text-red-600"
                  >
                    <Trash2 className="h-3.5 w-3.5" />
                  </button>
                </div>
                <p className="text-lg font-semibold text-ink-950">
                  {formatMoney(spent, currency, locale)}
                  <span className="text-sm font-normal text-ink-400"> / {formatMoney(Number(c.amount), currency, locale)}</span>
                </p>
                <Progress value={pct} tone={tone} className="my-3" />
                <div className="flex items-center justify-between text-xs text-ink-400">
                  <span>{pct}% {t("budget.ofBudget")}</span>
                  <span>{remaining >= 0 ? formatMoney(remaining, currency, locale) : formatMoney(0, currency, locale)} {t("budget.remaining").toLowerCase()}</span>
                </div>
                {pct >= 80 && (
                  <p className="mt-3 flex items-center gap-1.5 rounded-lg bg-amber-50 px-2.5 py-1.5 text-xs text-amber-800">
                    <AlertTriangle className="h-3.5 w-3.5 shrink-0" />
                    {t("budget.warning", { percent: pct, category: t(`expenses.categories.${c.category}`) })}
                  </p>
                )}
              </Card>
            );
          })}
        </div>
      )}

      <BudgetCategoryModal
        open={modalOpen}
        onClose={() => setModalOpen(false)}
        budgetId={budgetId}
        existingCategories={categories.map((c) => c.category)}
        onCreated={(c) => {
          setCategories((prev) => [...prev, c]);
          setModalOpen(false);
        }}
      />
    </div>
  );
}

function BudgetCategoryModal({
  open,
  onClose,
  budgetId,
  existingCategories,
  onCreated
}: {
  open: boolean;
  onClose: () => void;
  budgetId: string;
  existingCategories: string[];
  onCreated: (c: BudgetCategory) => void;
}) {
  const t = useTranslations();
  const {
    register,
    handleSubmit,
    reset,
    formState: { errors, isSubmitting }
  } = useForm<BudgetCategoryInput>({ resolver: zodResolver(budgetCategorySchema) });

  const available = CATEGORIES.filter((c) => !existingCategories.includes(c));

  async function onSubmit(values: BudgetCategoryInput) {
    const supabase = createClient();
    const { data: userData } = await supabase.auth.getUser();
    if (!userData.user || !budgetId) return;

    const { data, error } = await supabase
      .from("budget_categories")
      .insert({
        budget_id: budgetId,
        user_id: userData.user.id,
        category: values.category,
        amount: values.amount
      })
      .select()
      .single();

    if (!error && data) {
      onCreated(data);
      reset();
    }
  }

  return (
    <Modal open={open} onClose={onClose} title={t("budget.add")}>
      <form onSubmit={handleSubmit(onSubmit)} noValidate className="space-y-4">
        <div>
          <Label htmlFor="category">{t("expenses.category")}</Label>
          <Select id="category" {...register("category")}>
            {available.map((c) => (
              <option key={c} value={c}>
                {t(`expenses.categories.${c}`)}
              </option>
            ))}
          </Select>
        </div>
        <div>
          <Label htmlFor="amount">{t("expenses.amount")}</Label>
          <Input id="amount" type="number" step="0.01" error={errors.amount?.message} {...register("amount")} />
          <FieldError>{errors.amount?.message}</FieldError>
        </div>
        <div className="flex justify-end gap-2 pt-2">
          <Button type="button" variant="secondary" onClick={onClose}>
            {t("common.cancel")}
          </Button>
          <Button type="submit" loading={isSubmitting} disabled={available.length === 0}>
            {t("common.save")}
          </Button>
        </div>
      </form>
    </Modal>
  );
}
