"use client";

import { useEffect, useMemo, useState } from "react";
import { AppShell } from "@/components/app-shell";
import { apiFetch } from "@/lib/api";

type CreditScoreEntry = {
  id: string;
  score: number;
  bureau: string;
  source: string;
  model: string;
  scoreDate: string;
  factors?: Record<string, unknown>;
  change?: number | null;
};

type CreditScoreSummary = {
  latest: CreditScoreEntry | null;
  previous: CreditScoreEntry | null;
  change: number | null;
  averageScore: number | null;
  entryCount: number;
  latestByBureau: CreditScoreEntry[];
  trend: CreditScoreEntry[];
};

const bureaus = [
  { value: "experian", label: "Experian" },
  { value: "equifax", label: "Equifax" },
  { value: "transunion", label: "TransUnion" },
  { value: "unknown", label: "Unknown" },
];

const today = new Date().toISOString().slice(0, 10);

export default function CreditScorePage() {
  const [summary, setSummary] = useState<CreditScoreSummary | null>(null);
  const [entries, setEntries] = useState<CreditScoreEntry[]>([]);
  const [filter, setFilter] = useState("all");
  const [status, setStatus] = useState("");
  const [form, setForm] = useState({
    score: "",
    bureau: "experian",
    source: "manual",
    model: "fico_8",
    scoreDate: today,
    positiveFactors: "",
    negativeFactors: "",
  });

  const filteredEntries = useMemo(() => {
    if (filter === "all") return entries;
    return entries.filter((entry) => entry.bureau === filter);
  }, [entries, filter]);

  const scoreBand = (score?: number | null) => {
    if (!score) return "No score";
    if (score >= 800) return "Exceptional";
    if (score >= 740) return "Very good";
    if (score >= 670) return "Good";
    if (score >= 580) return "Fair";
    return "Needs work";
  };

  const load = async () => {
    const query = filter === "all" ? "" : `?bureau=${filter}`;
    const [summaryRes, entriesRes] = await Promise.all([
      apiFetch<CreditScoreSummary>("/api/credit-score/summary"),
      apiFetch<CreditScoreEntry[]>(`/api/credit-score/entries${query}`),
    ]);
    if (!summaryRes.error) setSummary(summaryRes.data ?? null);
    if (!entriesRes.error) setEntries(entriesRes.data ?? []);
  };

  useEffect(() => {
    load().catch(() => setStatus("Unable to load credit score history."));
  }, [filter]);

  const addEntry = async () => {
    const score = Number(form.score);
    if (!score || score < 300 || score > 850) {
      setStatus("Score must be between 300 and 850.");
      return;
    }
    const factors = {
      positive: form.positiveFactors.split(",").map((item) => item.trim()).filter(Boolean),
      negative: form.negativeFactors.split(",").map((item) => item.trim()).filter(Boolean),
    };
    const res = await apiFetch<CreditScoreEntry>("/api/credit-score/entries", {
      method: "POST",
      body: JSON.stringify({
        score,
        bureau: form.bureau,
        source: form.source,
        model: form.model,
        scoreDate: form.scoreDate,
        factors,
      }),
    });
    if (res.error) {
      setStatus(res.error.message ?? "Unable to add score entry.");
      return;
    }
    const change = res.data?.change;
    setStatus(change === null || change === undefined ? "Credit score entry added." : `Credit score entry added. Change: ${change > 0 ? "+" : ""}${change}.`);
    setForm((prev) => ({ ...prev, score: "", positiveFactors: "", negativeFactors: "" }));
    await load();
  };

  const inputCls = "mt-2 w-full rounded-xl border border-border bg-background/50 px-4 py-2 text-sm text-foreground focus:border-primary focus:ring-primary focus:outline-none";
  const labelCls = "text-xs text-muted-foreground font-semibold uppercase tracking-wider";

  return (
    <AppShell title="Credit Score" subtitle="Track bureau scores, history, factors, and score movement alerts.">
      <div className="space-y-6">
        <div className="grid gap-4 md:grid-cols-4">
          <div className="rounded-xl border border-border bg-secondary/10 p-5">
            <p className="text-xs text-muted-foreground">Latest score</p>
            <p className="mt-2 text-3xl font-bold text-foreground">{summary?.latest?.score ?? "--"}</p>
            <p className="mt-1 text-xs text-muted-foreground">{scoreBand(summary?.latest?.score)}</p>
          </div>
          <div className="rounded-xl border border-border bg-secondary/10 p-5">
            <p className="text-xs text-muted-foreground">Last change</p>
            <p className="mt-2 text-3xl font-bold text-foreground">
              {summary?.change === null || summary?.change === undefined ? "--" : `${summary.change > 0 ? "+" : ""}${summary.change}`}
            </p>
            <p className="mt-1 text-xs text-muted-foreground">Compared with previous same-bureau entry</p>
          </div>
          <div className="rounded-xl border border-border bg-secondary/10 p-5">
            <p className="text-xs text-muted-foreground">Average score</p>
            <p className="mt-2 text-3xl font-bold text-foreground">{summary?.averageScore ?? "--"}</p>
            <p className="mt-1 text-xs text-muted-foreground">Across saved entries</p>
          </div>
          <div className="rounded-xl border border-border bg-secondary/10 p-5">
            <p className="text-xs text-muted-foreground">Entries</p>
            <p className="mt-2 text-3xl font-bold text-foreground">{summary?.entryCount ?? 0}</p>
            <p className="mt-1 text-xs text-muted-foreground">Manual or imported history</p>
          </div>
        </div>

        <div className="grid gap-6 lg:grid-cols-[0.9fr_1.1fr]">
          <section className="rounded-xl border border-border bg-secondary/10 p-6">
            <p className="text-sm font-bold text-foreground">Add Score Entry</p>
            <div className="mt-4 grid gap-4 md:grid-cols-2">
              <div>
                <label className={labelCls}>Score</label>
                <input type="number" min={300} max={850} value={form.score} onChange={(event) => setForm((prev) => ({ ...prev, score: event.target.value }))} className={inputCls} />
              </div>
              <div>
                <label className={labelCls}>Bureau</label>
                <select value={form.bureau} onChange={(event) => setForm((prev) => ({ ...prev, bureau: event.target.value }))} className={inputCls}>
                  {bureaus.map((bureau) => <option key={bureau.value} value={bureau.value}>{bureau.label}</option>)}
                </select>
              </div>
              <div>
                <label className={labelCls}>Model</label>
                <select value={form.model} onChange={(event) => setForm((prev) => ({ ...prev, model: event.target.value }))} className={inputCls}>
                  <option value="fico_8">FICO 8</option>
                  <option value="fico_9">FICO 9</option>
                  <option value="vantage_score_3">VantageScore 3</option>
                  <option value="vantage_score_4">VantageScore 4</option>
                </select>
              </div>
              <div>
                <label className={labelCls}>Score date</label>
                <input type="date" value={form.scoreDate} onChange={(event) => setForm((prev) => ({ ...prev, scoreDate: event.target.value }))} className={inputCls} />
              </div>
              <div>
                <label className={labelCls}>Positive factors</label>
                <input value={form.positiveFactors} onChange={(event) => setForm((prev) => ({ ...prev, positiveFactors: event.target.value }))} className={inputCls} placeholder="low utilization, on-time payments" />
              </div>
              <div>
                <label className={labelCls}>Negative factors</label>
                <input value={form.negativeFactors} onChange={(event) => setForm((prev) => ({ ...prev, negativeFactors: event.target.value }))} className={inputCls} placeholder="hard inquiry, high balance" />
              </div>
            </div>
            <button onClick={addEntry} className="mt-4 rounded-lg bg-primary px-4 py-2.5 text-sm font-bold text-primary-foreground hover:bg-primary/90">
              Add Score
            </button>
            {status && <p className="mt-4 rounded-lg border border-border bg-background/60 px-4 py-3 text-sm text-muted-foreground">{status}</p>}
          </section>

          <section className="rounded-xl border border-border bg-secondary/10 p-6">
            <div className="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
              <p className="text-sm font-bold text-foreground">Bureau Snapshot</p>
              <select value={filter} onChange={(event) => setFilter(event.target.value)} className="rounded-lg border border-border bg-background/50 px-3 py-2 text-sm text-foreground">
                <option value="all">All bureaus</option>
                {bureaus.map((bureau) => <option key={bureau.value} value={bureau.value}>{bureau.label}</option>)}
              </select>
            </div>
            <div className="mt-4 grid gap-3 md:grid-cols-3">
              {(summary?.latestByBureau ?? []).map((entry) => (
                <div key={entry.bureau} className="rounded-lg border border-border bg-background/50 p-4">
                  <p className="text-xs uppercase text-muted-foreground">{entry.bureau}</p>
                  <p className="mt-2 text-2xl font-bold text-foreground">{entry.score}</p>
                  <p className="text-xs text-muted-foreground">{new Date(entry.scoreDate).toLocaleDateString()}</p>
                </div>
              ))}
              {(summary?.latestByBureau?.length ?? 0) === 0 && <p className="text-sm text-muted-foreground">No bureau scores yet.</p>}
            </div>
          </section>
        </div>

        <section className="rounded-xl border border-border bg-secondary/10 p-6">
          <p className="text-sm font-bold text-foreground">Score History</p>
          <div className="mt-4 divide-y divide-border">
            {filteredEntries.length === 0 && <p className="py-8 text-sm text-muted-foreground">No score entries for this view.</p>}
            {filteredEntries.map((entry) => {
              const factors = entry.factors ?? {};
              const positive = Array.isArray(factors.positive) ? factors.positive : [];
              const negative = Array.isArray(factors.negative) ? factors.negative : [];
              return (
                <article key={entry.id} className="py-4">
                  <div className="flex flex-col gap-3 md:flex-row md:items-start md:justify-between">
                    <div>
                      <div className="flex flex-wrap items-center gap-2">
                        <p className="text-lg font-bold text-foreground">{entry.score}</p>
                        <span className="rounded-full border border-border px-2 py-0.5 text-xs text-muted-foreground">{entry.bureau}</span>
                        <span className="rounded-full border border-border px-2 py-0.5 text-xs text-muted-foreground">{entry.model}</span>
                      </div>
                      <p className="mt-1 text-sm text-muted-foreground">{new Date(entry.scoreDate).toLocaleDateString()} · {entry.source}</p>
                      {(positive.length > 0 || negative.length > 0) && (
                        <p className="mt-2 text-xs text-muted-foreground">
                          {positive.length > 0 ? `Positive: ${positive.join(", ")}` : ""}
                          {positive.length > 0 && negative.length > 0 ? " · " : ""}
                          {negative.length > 0 ? `Negative: ${negative.join(", ")}` : ""}
                        </p>
                      )}
                    </div>
                    <p className="text-sm font-semibold text-foreground">{scoreBand(entry.score)}</p>
                  </div>
                </article>
              );
            })}
          </div>
        </section>
      </div>
    </AppShell>
  );
}
