"use client";

import { useMemo, useState } from "react";
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { useAlertConfirm } from "@/components/ui/alert-dialog";
import { useLocalStorage } from "@/lib/hooks/use-local-storage";
import {
  GRANTS_SEED,
  GRANT_CATEGORIES,
  APPLICATION_STATUSES,
  statusVariant,
  type GrantCategory,
  type ApplicationStatus,
  type GrantProgram,
} from "@/lib/sag/grants-seed";
import { ALL_ORGANIZATIONS } from "@/lib/sag/entities";
import { formatDate } from "@/lib/utils";

interface Application {
  id: string;
  grantId: string;
  entitySlug: string;
  status: ApplicationStatus;
  appliedDate?: string;
  awardAmount?: number;
  notes?: string;
  createdAt: string;
}

export function GrantsTracker() {
  const [applications, setApplications] = useLocalStorage<Application[]>("sag.grants.applications", []);
  const [filterCategory, setFilterCategory] = useState<GrantCategory | "all">("all");
  const [expandedId, setExpandedId] = useState<string | null>(null);
  const [addingFor, setAddingFor] = useState<string | null>(null);
  const { confirm: confirmAlert, AlertConfirmPortal } = useAlertConfirm();

  const filtered = useMemo(
    () => GRANTS_SEED.filter((g) => filterCategory === "all" || g.category === filterCategory),
    [filterCategory]
  );

  const stats = useMemo(() => {
    const inProgress = applications.filter((a) => ["Researching", "In Progress", "Submitted"].includes(a.status)).length;
    const awarded = applications.filter((a) => a.status === "Awarded");
    const awardedTotal = awarded.reduce((sum, a) => sum + (a.awardAmount ?? 0), 0);
    return {
      programs: GRANTS_SEED.length,
      applications: applications.length,
      inProgress,
      awarded: awarded.length,
      awardedTotal,
    };
  }, [applications]);

  function addApplication(grantId: string, entitySlug: string, status: ApplicationStatus) {
    const now = new Date();
    setApplications([
      ...applications,
      {
        // eslint-disable-next-line react-hooks/purity -- intentional UUID-like generation in event handler
        id: `app-${now.getTime()}-${Math.random().toString(36).slice(2, 7)}`,
        grantId,
        entitySlug,
        status,
        createdAt: now.toISOString(),
      },
    ]);
    setAddingFor(null);
  }

  function updateApp(id: string, patch: Partial<Application>) {
    setApplications(applications.map((a) => (a.id === id ? { ...a, ...patch } : a)));
  }

  async function deleteApp(id: string) {
    const ok = await confirmAlert({
      title: "Delete this application record?",
      description: "This permanently removes the record. Cannot be undone.",
      actionLabel: "Delete",
      destructive: true,
    });
    if (!ok) return;
    setApplications(applications.filter((a) => a.id !== id));
  }

  return (
    <>
    <div className="space-y-6">
      <section className="grid gap-4 md:grid-cols-5">
        <Stat label="Programs in registry" value={String(stats.programs)} />
        <Stat label="Applications" value={String(stats.applications)} />
        <Stat label="In progress" value={String(stats.inProgress)} tone="info" />
        <Stat label="Awarded" value={String(stats.awarded)} tone="success" />
        <Stat label="$ awarded total" value={`$${stats.awardedTotal.toLocaleString()}`} tone="success" />
      </section>

      <Card>
        <CardContent className="p-4 flex flex-wrap items-center gap-2">
          <span className="text-sm font-medium">Category:</span>
          <Chip active={filterCategory === "all"} onClick={() => setFilterCategory("all")}>All ({GRANTS_SEED.length})</Chip>
          {GRANT_CATEGORIES.map((c) => {
            const count = GRANTS_SEED.filter((g) => g.category === c).length;
            if (count === 0) return null;
            return (
              <Chip key={c} active={filterCategory === c} onClick={() => setFilterCategory(c)}>
                {c} ({count})
              </Chip>
            );
          })}
        </CardContent>
      </Card>

      <div className="space-y-3">
        {filtered.map((grant) => {
          const grantApps = applications.filter((a) => a.grantId === grant.id);
          const expanded = expandedId === grant.id;
          return (
            <Card key={grant.id}>
              <CardContent className="p-5">
                <div className="flex items-start justify-between gap-4 flex-wrap">
                  <div className="min-w-0 flex-1">
                    <div className="flex items-center gap-2 flex-wrap mb-1">
                      <Badge variant="outline" className="text-[10px]">{grant.category}</Badge>
                      <Badge variant="secondary" className="text-[10px]">{grant.cadence}</Badge>
                      {grantApps.length > 0 && (
                        <Badge variant="info" className="text-[10px]">
                          {grantApps.length} application{grantApps.length === 1 ? "" : "s"}
                        </Badge>
                      )}
                    </div>
                    <h3 className="text-base font-semibold">{grant.name}</h3>
                    <p className="text-xs text-muted-foreground mt-0.5">
                      {grant.funder}
                      {grant.fundingRange && ` · ${grant.fundingRange}`}
                    </p>
                  </div>
                  <div className="flex items-center gap-2 shrink-0">
                    <Button asChild variant="outline" size="sm">
                      <a href={grant.applicationUrl} target="_blank" rel="noopener noreferrer">Apply ↗</a>
                    </Button>
                    <Button variant="ghost" size="sm" onClick={() => setExpandedId(expanded ? null : grant.id)}>
                      {expanded ? "Close" : "Details"}
                    </Button>
                  </div>
                </div>

                {expanded && (
                  <div className="mt-4 grid gap-4 md:grid-cols-2">
                    <div>
                      <Label>Eligibility</Label>
                      <p className="mt-1 text-sm leading-relaxed">{grant.eligibility}</p>
                    </div>
                    <div>
                      <Label>SAG fit</Label>
                      <p className="mt-1 text-sm leading-relaxed">{grant.saaFit}</p>
                    </div>
                    {grant.nextDeadline && (
                      <div>
                        <Label>Next deadline</Label>
                        <p className="mt-1 text-sm">{grant.nextDeadline}</p>
                      </div>
                    )}
                    {grant.notes && (
                      <div className="md:col-span-2">
                        <Label>Notes</Label>
                        <p className="mt-1 text-sm italic text-muted-foreground">{grant.notes}</p>
                      </div>
                    )}

                    <div className="md:col-span-2 mt-2 pt-4 border-t">
                      <div className="flex items-center justify-between mb-2">
                        <Label>Applications for this grant</Label>
                        <Button variant="brand" size="sm" onClick={() => setAddingFor(addingFor === grant.id ? null : grant.id)}>
                          {addingFor === grant.id ? "Cancel" : "+ Track application"}
                        </Button>
                      </div>

                      {addingFor === grant.id && <AddApplicationForm grant={grant} onAdd={(slug, status) => addApplication(grant.id, slug, status)} />}

                      {grantApps.length === 0 ? (
                        <p className="text-xs text-muted-foreground italic">No applications tracked yet.</p>
                      ) : (
                        <ul className="space-y-2">
                          {grantApps.map((app) => {
                            const org = ALL_ORGANIZATIONS.find((o) => o.slug === app.entitySlug);
                            return (
                              <li key={app.id} className="rounded-md border bg-background p-3 text-sm">
                                <div className="flex items-center justify-between gap-3 flex-wrap">
                                  <div className="flex items-center gap-2 min-w-0">
                                    <span>{org?.emoji ?? "🏢"}</span>
                                    <span className="font-medium">{org?.name ?? app.entitySlug}</span>
                                    <Badge variant={statusVariant(app.status)} className="text-[10px]">{app.status}</Badge>
                                  </div>
                                  <div className="flex items-center gap-1">
                                    <select
                                      value={app.status}
                                      onChange={(e) => updateApp(app.id, { status: e.target.value as ApplicationStatus })}
                                      className="h-8 rounded-md border border-input bg-background px-2 text-xs"
                                    >
                                      {APPLICATION_STATUSES.map((s) => (
                                        <option key={s} value={s}>{s}</option>
                                      ))}
                                    </select>
                                    {app.status === "Awarded" && (
                                      <Input
                                        type="number"
                                        placeholder="$ award"
                                        value={app.awardAmount ?? ""}
                                        onChange={(e) => updateApp(app.id, { awardAmount: parseFloat(e.target.value) || undefined })}
                                        className="h-8 w-28 text-xs"
                                      />
                                    )}
                                    <Button variant="ghost" size="sm" onClick={() => deleteApp(app.id)}>×</Button>
                                  </div>
                                </div>
                                <Input
                                  placeholder="Notes (deadline, contact, status updates...)"
                                  value={app.notes ?? ""}
                                  onChange={(e) => updateApp(app.id, { notes: e.target.value })}
                                  className="mt-2 text-xs h-8"
                                />
                                {app.awardAmount && (
                                  <div className="mt-1 text-xs text-green-700 dark:text-green-400">
                                    ✓ Awarded ${app.awardAmount.toLocaleString()}
                                  </div>
                                )}
                                <div className="mt-1 text-[10px] text-muted-foreground">
                                  Tracked since {formatDate(app.createdAt)}
                                </div>
                              </li>
                            );
                          })}
                        </ul>
                      )}
                    </div>
                  </div>
                )}
              </CardContent>
            </Card>
          );
        })}
      </div>

      <p className="text-xs text-muted-foreground">
        Programs above are seeded — actual deadlines + amounts change year to year. Confirm each opportunity at the funder’s website before relying on details here. Application status is tracked in localStorage.
      </p>
    </div>
    <AlertConfirmPortal />
    </>
  );
}

function AddApplicationForm({ onAdd }: { grant: GrantProgram; onAdd: (slug: string, status: ApplicationStatus) => void }) {
  const [slug, setSlug] = useState(ALL_ORGANIZATIONS[0]?.slug ?? "south-armz-global");
  const [status, setStatus] = useState<ApplicationStatus>("Researching");
  return (
    <div className="mb-3 grid gap-2 md:grid-cols-[2fr_1fr_auto] items-end">
      <div>
        <Label>Entity</Label>
        <select
          value={slug}
          onChange={(e) => setSlug(e.target.value)}
          className="mt-1 w-full h-9 rounded-md border border-input bg-background px-2 text-sm"
        >
          {ALL_ORGANIZATIONS.map((o) => (
            <option key={o.slug} value={o.slug}>{o.emoji} {o.name}</option>
          ))}
        </select>
      </div>
      <div>
        <Label>Status</Label>
        <select
          value={status}
          onChange={(e) => setStatus(e.target.value as ApplicationStatus)}
          className="mt-1 w-full h-9 rounded-md border border-input bg-background px-2 text-sm"
        >
          {APPLICATION_STATUSES.map((s) => (
            <option key={s} value={s}>{s}</option>
          ))}
        </select>
      </div>
      <Button variant="brand" size="sm" onClick={() => onAdd(slug, status)}>Add</Button>
    </div>
  );
}

function Chip({ active, onClick, children }: { active: boolean; onClick: () => void; children: React.ReactNode }) {
  return (
    <button
      onClick={onClick}
      className={`text-xs px-3 py-1.5 rounded-full border transition-colors ${
        active ? "bg-foreground text-background border-foreground" : "border-input text-muted-foreground hover:bg-accent"
      }`}
    >
      {children}
    </button>
  );
}

function Stat({ label, value, tone = "default" }: { label: string; value: string; tone?: "default" | "success" | "info" }) {
  const color =
    tone === "success" ? "text-green-700 dark:text-green-400" : tone === "info" ? "text-blue-700 dark:text-blue-400" : "text-foreground";
  return (
    <Card>
      <CardContent className="p-5">
        <div className="text-xs uppercase tracking-wider text-muted-foreground">{label}</div>
        <div className={`mt-1 text-2xl font-semibold tabular-nums ${color}`}>{value}</div>
      </CardContent>
    </Card>
  );
}

function Label({ children }: { children: React.ReactNode }) {
  return <span className="section-label font-medium">{children}</span>;
}
