"use client";

import { useEffect, useMemo, useState } from "react";
import { useGroupsContext } from "@/hooks/groups-context";
import useBuckets from "@/features/buckets/hooks/use-buckets";
import useTags from "@/features/tags/hooks/use-tags";
import NewBucketModal from "@/components/new-bucket-modal";
import ConfirmSlideModal from "@/components/confirm-slide-modal";
import { bucketIcons } from "@/lib/shared/bucket-icons";
import BucketCard from "./bucket-card";
import { useEntryMutation } from "@/hooks/entry-mutation-context";
import { useNotificationsContext } from "@/hooks/notifications-context";

export default function BucketsPanel() {
    const { activeGroupId } = useGroupsContext();
    const { buckets, loading, error, createBucket, updateBucket, deleteBucket, reload } = useBuckets(activeGroupId);
    const { mutationVersion } = useEntryMutation();
    const { notify } = useNotificationsContext();
    const { tags: tagSuggestions } = useTags(activeGroupId);
    const [modalOpen, setModalOpen] = useState(false);
    const [editId, setEditId] = useState<number | null>(null);
    const [confirmDeleteId, setConfirmDeleteId] = useState<number | null>(null);
    const [form, setForm] = useState({
        name: "",
        description: "",
        iconKey: "none",
        budgetLimitDollars: "",
        tags: [] as string[],
        necessity: "BOTH",
        windowDays: "30"
    });

    const iconMap = useMemo(() => new Map(bucketIcons.map(item => [item.key, item.icon])), []);
    const orderedBuckets = useMemo(() => [...buckets].sort((a, b) => a.position - b.position || a.name.localeCompare(b.name)), [buckets]);

    useEffect(() => {
        if (!activeGroupId) return;
        if (mutationVersion === 0) return;
        reload();
    }, [mutationVersion, activeGroupId, reload]);

    function resetForm() {
        setForm({ name: "", description: "", iconKey: "none", budgetLimitDollars: "", tags: [], necessity: "BOTH", windowDays: "30" });
        setEditId(null);
    }

    function openCreate() {
        resetForm();
        setModalOpen(true);
    }

    function openEdit(bucketId: number) {
        const bucket = buckets.find(item => item.id === bucketId);
        if (!bucket) return;
        setEditId(bucketId);
        setForm({
            name: bucket.name,
            description: bucket.description || "",
            iconKey: bucket.iconKey || "none",
            budgetLimitDollars: bucket.budgetLimitDollars != null ? String(bucket.budgetLimitDollars) : "",
            tags: bucket.tags || [],
            necessity: bucket.necessity,
            windowDays: bucket.windowDays ? String(bucket.windowDays) : "30"
        });
        setModalOpen(true);
    }

    async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
        e.preventDefault();
        const budget = form.budgetLimitDollars ? Number(form.budgetLimitDollars) : null;
        const windowDays = form.windowDays ? Number(form.windowDays) : 30;
        if (!form.name.trim()) return;
        const iconKey = form.iconKey && form.iconKey !== "none" ? form.iconKey : null;
        if (!Number.isFinite(windowDays) || windowDays < 1 || windowDays > 365) return;

        if (editId) {
            const ok = await updateBucket({
                id: editId,
                name: form.name.trim(),
                description: form.description.trim() || undefined,
                iconKey,
                budgetLimitDollars: budget,
                tags: form.tags,
                necessity: form.necessity as "NECESSARY" | "BOTH" | "UNNECESSARY",
                windowDays
            });
            if (ok) {
                notify({ title: "Bucket updated", message: form.name.trim(), tone: "success" });
                setModalOpen(false);
            }
        } else {
            const ok = await createBucket({
                name: form.name.trim(),
                description: form.description.trim() || undefined,
                iconKey,
                budgetLimitDollars: budget,
                tags: form.tags,
                necessity: form.necessity as "NECESSARY" | "BOTH" | "UNNECESSARY",
                windowDays
            });
            if (ok) {
                notify({ title: "Bucket created", message: form.name.trim(), tone: "success" });
                setModalOpen(false);
            }
        }
    }

    function budgetUsage(bucket: typeof buckets[number]) {
        const limit = bucket.budgetLimitDollars || 0;
        const spent = bucket.totalUsage || 0;
        return { limit, spent };
    }

    return (
        <>
            <div className="panel panel-accent p-4">
                <div className="card-header">
                    <h2 className="card-title text-lg">Buckets</h2>
                    <button
                        type="button"
                        onClick={openCreate}
                        className="flex h-8 w-8 -translate-y-0.5 items-center justify-center rounded-full border border-accent bg-panel text-lg font-semibold leading-none hover:border-accent-strong disabled:opacity-50"
                        disabled={!activeGroupId}
                        aria-label="Add bucket"
                    >
                        +
                    </button>
                </div>
                <div className="mt-3 grid gap-3 [grid-template-columns:repeat(auto-fit,minmax(260px,1fr))]">


                    {!activeGroupId ? (
                        <div className="text-sm text-muted">Select a group to view buckets.</div>
                    ) : loading ? (
                        <div className="space-y-2">
                            {[0, 1].map(row => (
                                <div key={row} className="rounded-lg border border-accent-weak bg-panel px-3 py-3">
                                    <div className="animate-pulse space-y-2">
                                        <div className="h-4 w-28 rounded bg-surface" />
                                        <div className="h-3 w-40 rounded bg-surface" />
                                    </div>
                                </div>
                            ))}
                        </div>


                    ) : orderedBuckets.length ? (
                        orderedBuckets.map(bucket => {
                            const icon = bucket.iconKey ? iconMap.get(bucket.iconKey) : null;
                            const { limit, spent } = budgetUsage(bucket);
                            const usageLabel = limit ? `$${spent.toFixed(2)} / $${limit.toFixed(2)}` : "";
                            return <BucketCard
                                key={bucket.id}
                                bucket={bucket}
                                icon={icon}
                                openEdit={openEdit}
                                limit={limit}
                                usageLabel={usageLabel}
                            />
                        })
                    ) : (
                        <div className="text-sm text-muted">No buckets yet.</div>
                    )}
                </div>
            </div>
            <NewBucketModal
                isOpen={modalOpen}
                title={editId ? "Edit bucket" : "New bucket"}
                form={form}
                error={error}
                onClose={() => setModalOpen(false)}
                onSubmit={handleSubmit}
                onChange={next => setForm(prev => ({ ...prev, ...next }))}
                tagSuggestions={tagSuggestions}
                canDelete={Boolean(editId)}
                onDelete={() => {
                    if (!editId) return;
                    setConfirmDeleteId(editId);
                }}
            />
            <ConfirmSlideModal
                isOpen={Boolean(confirmDeleteId)}
                title="Delete bucket"
                description="This will permanently remove the bucket."
                confirmLabel="Delete bucket"
                onClose={() => setConfirmDeleteId(null)}
                onConfirm={async () => {
                    if (!confirmDeleteId) return;
                    const deletedBucket = buckets.find(bucket => bucket.id === confirmDeleteId) || null;
                    const ok = await deleteBucket(confirmDeleteId);
                    if (ok) {
                        notify({
                            title: "Bucket deleted",
                            message: deletedBucket?.name || "Bucket removed",
                            tone: "danger"
                        });
                        setConfirmDeleteId(null);
                        setModalOpen(false);
                        resetForm();
                    }
                }}
            />
        </>
    );
}

