import { createFileRoute, useRouter, Link } from "@tanstack/react-router";
import { useServerFn } from "@tanstack/react-start";
import { useQuery } from "@tanstack/react-query";
import { supabase } from "@/integrations/supabase/client";
import { structuredBrief, healthScore } from "@/lib/ai.functions";
import { GlassCard, SectionLabel } from "@/components/GlassCard";
import { formatCompact, formatCurrency, relativeDay } from "@/lib/format";
import { Plus, Sparkles, Bell, Settings2, TrendingUp, TrendingDown, Target, Wallet, BarChart3, PieChart as PieIcon, LineChart as LineIcon, Activity, PiggyBank } from "lucide-react";
import { useMemo, useState } from "react";
import { HealthRing } from "@/components/HealthRing";
import { AuraLineChart, TIMEFRAMES, type SeriesPoint, type TimeframeKey } from "@/components/charts/AuraLineChart";
import { deriveChips, StatusChipRow } from "@/components/StatusChips";
import { Skeleton } from "@/components/ui/skeleton";
import { DisclaimerNote } from "@/components/legal/DisclaimerNote";
import { IntelligencePanel } from "@/components/IntelligencePanel";

import {
  monthTotals,
  netWorth as computeNetWorth,
  netWorthSeries as buildNetWorthSeries,
} from "@/lib/finance";

export const Route = createFileRoute("/_authenticated/home")({
  head: () => ({
    meta: [
      { title: "Home — PRUDENTIA" },
      { name: "description", content: "Your PRUDENTIA cockpit: health score, net worth, cash flow, trends, and AI insights." },
      { property: "og:title", content: "Home — PRUDENTIA" },
      { property: "og:description", content: "Your AI financial cockpit." },
    ],
  }),
  component: Home,
});

type ChartKey =
  | "net_worth" | "cash_flow" | "income_expense" | "savings"
  | "health" | "investment" | "budget" | "goal" | "categories";

const CHART_TABS: { key: ChartKey; label: string; icon: any }[] = [
  { key: "net_worth", label: "Net Worth", icon: TrendingUp },
  { key: "cash_flow", label: "Cash Flow", icon: Activity },
  { key: "income_expense", label: "Income vs Expenses", icon: BarChart3 },
  { key: "savings", label: "Savings", icon: PiggyBank },
  { key: "health", label: "Health", icon: Sparkles },
  { key: "investment", label: "Investments", icon: LineIcon },
  { key: "budget", label: "Budgets", icon: Wallet },
  { key: "goal", label: "Goals", icon: Target },
  { key: "categories", label: "Categories", icon: PieIcon },
];

function Home() {
  const { user } = Route.useRouteContext();
  const router = useRouter();

  const profileQ = useQuery({
    queryKey: ["profile", user.id],
    queryFn: async () => (await supabase.from("profiles").select("*").eq("id", user.id).single()).data,
  });
  const txQ = useQuery({
    queryKey: ["tx", user.id],
    queryFn: async () => (await supabase.from("transactions").select("*").eq("user_id", user.id).order("occurred_at", { ascending: true })).data ?? [],
  });
  const budgetQ = useQuery({
    queryKey: ["budgets", user.id],
    queryFn: async () => (await supabase.from("budgets").select("*").eq("user_id", user.id)).data ?? [],
  });
  const goalsQ = useQuery({
    queryKey: ["goals", user.id],
    queryFn: async () => (await supabase.from("goals").select("*").eq("user_id", user.id)).data ?? [],
  });

  const briefFn = useServerFn(structuredBrief);
  const healthFn = useServerFn(healthScore);
  const briefQ = useQuery({ queryKey: ["brief-structured", user.id], queryFn: () => briefFn(), staleTime: 60_000 * 30 });
  const healthQ = useQuery({ queryKey: ["health", user.id], queryFn: () => healthFn(), staleTime: 60_000 * 10 });

  const currency = profileQ.data?.currency ?? "USD";
  const name = (profileQ.data?.name as string) ?? "there";
  const firstName = name.split(" ")[0];
  const savings0 = Number(profileQ.data?.savings ?? 0);
  const income = Number(profileQ.data?.monthly_income ?? 0);
  const txs = txQ.data ?? [];

  const monthTxs = useMemo(() => {
    const now = new Date();
    return txs.filter((t: any) => {
      const d = new Date(t.occurred_at);
      return d.getMonth() === now.getMonth() && d.getFullYear() === now.getFullYear();
    });
  }, [txs]);
  const { earned, spent, net } = useMemo(() => monthTotals(txs as any), [txs]);
  // Baseline savings + every recorded transaction — matches the chart's final point.
  const netWorthValue = useMemo(() => computeNetWorth(savings0, txs as any), [savings0, txs]);

  // --- Series builders (all in ms epoch) ---
  const netWorthSeries: SeriesPoint[] = useMemo(
    () => buildNetWorthSeries(savings0, txs as any),
    [txs, savings0],
  );

  // Bucketize to daily rollup for cash flow / income / expense
  const dailyRollup = useMemo(() => {
    const map = new Map<number, { income: number; expense: number }>();
    txs.forEach((t: any) => {
      const d = new Date(t.occurred_at);
      const key = new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();
      const row = map.get(key) ?? { income: 0, expense: 0 };
      if (t.type === "income") row.income += Number(t.amount); else row.expense += Number(t.amount);
      map.set(key, row);
    });
    return [...map.entries()].sort((a, b) => a[0] - b[0]).map(([t, v]) => ({ t, ...v }));
  }, [txs]);

  const cashFlowSeries: SeriesPoint[] = useMemo(() =>
    dailyRollup.map((d) => ({ t: d.t, value: Math.round(d.income - d.expense) })), [dailyRollup]);
  const incomeSeries: SeriesPoint[] = useMemo(() =>
    dailyRollup.map((d) => ({ t: d.t, value: Math.round(d.income) })), [dailyRollup]);
  const expenseSeries: SeriesPoint[] = useMemo(() =>
    dailyRollup.map((d) => ({ t: d.t, value: Math.round(d.expense) })), [dailyRollup]);

  // Monthly savings (income - expense per month, cumulative)
  const savingsSeries: SeriesPoint[] = useMemo(() => {
    const map = new Map<number, number>();
    txs.forEach((t: any) => {
      const d = new Date(t.occurred_at);
      const key = new Date(d.getFullYear(), d.getMonth(), 1).getTime();
      map.set(key, (map.get(key) ?? 0) + (t.type === "income" ? 1 : -1) * Number(t.amount));
    });
    const arr = [...map.entries()].sort((a, b) => a[0] - b[0]);
    let cum = 0;
    return arr.map(([t, v]) => { cum += v; return { t, value: Math.round(cum) }; });
  }, [txs]);

  // Health trend — synthesize from monthly cashflow ratios (deterministic proxy)
  const healthSeries: SeriesPoint[] = useMemo(() => {
    const map = new Map<number, { i: number; e: number }>();
    txs.forEach((t: any) => {
      const d = new Date(t.occurred_at);
      const key = new Date(d.getFullYear(), d.getMonth(), 1).getTime();
      const row = map.get(key) ?? { i: 0, e: 0 };
      if (t.type === "income") row.i += Number(t.amount); else row.e += Number(t.amount);
      map.set(key, row);
    });
    return [...map.entries()].sort((a, b) => a[0] - b[0]).map(([t, v]) => {
      const inc = v.i || income || 1;
      const savingsRate = Math.max(-1, Math.min(1, (v.i - v.e) / inc));
      const score = Math.round(50 + savingsRate * 50);
      return { t, value: Math.max(1, Math.min(100, score)) };
    });
  }, [txs, income]);

  // Investment growth — 6% APY on savings baseline over time
  const investmentSeries: SeriesPoint[] = useMemo(() => {
    if (savings0 <= 0) return [];
    const arr: SeriesPoint[] = [];
    const start = Date.now() - 365 * 86_400_000;
    for (let m = 0; m <= 12; m++) {
      const t = start + m * 30 * 86_400_000;
      const value = Math.round(savings0 * Math.pow(1 + 0.06 / 12, m));
      arr.push({ t, value });
    }
    return arr;
  }, [savings0]);

  // Budget progress — % used so far
  const budgetTotal = (budgetQ.data ?? []).reduce((s: number, b: any) => s + Number(b.monthly_limit), 0);
  const budgetUsed = monthTxs.filter((t: any) => t.type === "expense" && (budgetQ.data ?? []).some((b: any) => b.category === t.category)).reduce((s, t: any) => s + Number(t.amount), 0);
  const budgetPct = budgetTotal > 0 ? (budgetUsed / budgetTotal) * 100 : 0;
  const budgetSeries: SeriesPoint[] = useMemo(() => {
    if (!budgetTotal) return [];
    const now = new Date();
    const start = new Date(now.getFullYear(), now.getMonth(), 1).getTime();
    const arr: SeriesPoint[] = [];
    let cum = 0;
    for (let day = 0; day < now.getDate(); day++) {
      const t = start + day * 86_400_000;
      const dayTxs = monthTxs.filter((tx: any) => new Date(tx.occurred_at).getDate() === day + 1 && tx.type === "expense");
      cum += dayTxs.reduce((s: number, tx: any) => s + Number(tx.amount), 0);
      arr.push({ t, value: Math.round((cum / budgetTotal) * 100) });
    }
    return arr;
  }, [monthTxs, budgetTotal]);

  // Goal progress — average % across goals over time (using current amounts)
  const goalSeries: SeriesPoint[] = useMemo(() => {
    const gs = goalsQ.data ?? [];
    if (!gs.length) return [];
    const avgPct = gs.reduce((s: number, g: any) => s + Math.min(100, (Number(g.current_amount) / Number(g.target_amount)) * 100), 0) / gs.length;
    // simple constant series with a slight upward tilt from history if we have tx
    const points = 12;
    return Array.from({ length: points }, (_, i) => ({
      t: Date.now() - (points - 1 - i) * 30 * 86_400_000,
      value: Math.round(Math.max(0, avgPct - (points - 1 - i) * 1.5)),
    }));
  }, [goalsQ.data]);

  // Categories — top 5 by monthly spend
  const categorySeries: SeriesPoint[] = useMemo(() => {
    const m = new Map<string, number>();
    monthTxs.filter((t: any) => t.type === "expense").forEach((t: any) => m.set(t.category, (m.get(t.category) ?? 0) + Number(t.amount)));
    return [...m.entries()].sort((a, b) => b[1] - a[1]).slice(0, 8).map(([_, v], i) => ({ t: i, value: Math.round(v) }));
  }, [monthTxs]);

  const [activeChart, setActiveChart] = useState<ChartKey>("net_worth");
  const [timeframe, setTimeframe] = useState<TimeframeKey>("30d");

  const chartConfig: Record<ChartKey, { title: string; data: SeriesPoint[]; color: string; format?: "currency" | "number" | "percent"; subtitle?: string; empty?: string }> = {
    net_worth: { title: "Net Worth", data: netWorthSeries, color: "var(--electric)", subtitle: `Baseline ${formatCurrency(savings0, currency)}` },
    cash_flow: { title: "Cash Flow", data: cashFlowSeries, color: "var(--purple)" },
    income_expense: { title: "Income vs Expenses", data: incomeSeries, color: "var(--success)", subtitle: "Income" },
    savings: { title: "Monthly Savings", data: savingsSeries, color: "var(--electric)", subtitle: "Cumulative net" },
    health: { title: "Financial Health", data: healthSeries, color: "var(--purple)", format: "percent" },
    investment: { title: "Investment Growth", data: investmentSeries, color: "var(--success)", subtitle: "6% projection on savings" },
    budget: { title: "Budget Progress", data: budgetSeries, color: "var(--warning)", format: "percent", subtitle: `${budgetPct.toFixed(0)}% of monthly limit` },
    goal: { title: "Goal Progress", data: goalSeries, color: "var(--purple)", format: "percent" },
    categories: { title: "Top Spending Categories", data: categorySeries, color: "var(--electric)" },
  };
  const active = chartConfig[activeChart];

  // Chips
  const savingsMonths = income > 0 ? savings0 / income : 0;
  const goalOnTrack = (goalsQ.data ?? []).some((g: any) => Number(g.current_amount) / Number(g.target_amount) >= 0.4);
  const chips = deriveChips({ savingsMonths, net, earned, spent, budgetOveragePct: budgetPct, goalOnTrack });

  const todayStr = new Date().toLocaleDateString(undefined, { weekday: "long", month: "long", day: "numeric" });
  const brief = briefQ.data;

  // Health delta = current vs earlier month
  const healthDelta = healthSeries.length >= 2 && healthQ.data ? healthQ.data.score - healthSeries[healthSeries.length - 2].value : undefined;

  return (
    <div className="px-4 pt-8 space-y-6">
      {/* Header */}
      <header className="flex items-end justify-between px-2">
        <div>
          <p className="text-[11px] text-muted-foreground uppercase tracking-widest">{todayStr}</p>
          <h1 className="text-2xl font-semibold mt-1">Good morning, {firstName}</h1>
        </div>
        <div className="flex items-center gap-2">
          <Link to="/analytics" className="size-10 rounded-full glass grid place-items-center" aria-label="Analytics">
            <BarChart3 className="size-4" />
          </Link>
          <Link to="/settings" className="size-10 rounded-full glass grid place-items-center" aria-label="Settings">
            <Settings2 className="size-4" />
          </Link>
          <Link to="/profile" className="size-10 rounded-full glass grid place-items-center" aria-label="Profile">
            <div className="size-6 rounded-full bg-gradient-to-br from-electric to-purple" />
          </Link>
        </div>
      </header>

      {/* Structured AI briefing */}
      <section className="relative">
        <div className="absolute -top-10 -left-10 size-48 bg-electric/20 blur-[80px] rounded-full pointer-events-none" />
        <div className="absolute -bottom-10 -right-10 size-48 bg-purple/20 blur-[80px] rounded-full pointer-events-none" />
        <GlassCard className="relative space-y-4">
          <div className="flex items-center gap-2 text-electric">
            <Sparkles className="size-4" />
            <span className="text-[11px] font-semibold tracking-[0.25em] uppercase">Morning Brief</span>
          </div>

          {briefQ.isLoading ? (
            <div className="space-y-2">
              <Skeleton className="h-5 w-2/3" />
              <Skeleton className="h-4 w-full" />
              <Skeleton className="h-4 w-5/6" />
            </div>
          ) : brief ? (
            <>
              <p className="text-[17px] leading-snug font-medium">{brief.greeting}</p>
              {brief.snapshot && <BriefLine label="Today's snapshot" value={brief.snapshot} />}
              <div className="grid grid-cols-2 gap-2 pt-1">
                <BriefStat label="Net Worth" value={formatCompact(netWorthValue, currency)} />
                <BriefStat label="This Month Net" value={`${net >= 0 ? "+" : ""}${formatCompact(net, currency)}`} tone={net >= 0 ? "success" : "warn"} />
                <BriefStat label="Today's Spend" value={formatCompact(monthTxs.filter((t: any) => new Date(t.occurred_at).toDateString() === new Date().toDateString() && t.type === "expense").reduce((s: number, t: any) => s + Number(t.amount), 0), currency)} />
                <BriefStat label="Income (M)" value={formatCompact(earned, currency)} tone="success" />
              </div>
              {chips.length > 0 && <div className="pt-1"><StatusChipRow chips={chips} /></div>}
              {brief.mission && <BriefLine icon="mission" label="Today's Mission" value={brief.mission} />}
              {brief.opportunity && <BriefLine icon="opp" label="Today's Opportunity" value={brief.opportunity} />}
              {brief.risk && <BriefLine icon="risk" label="Today's Risk" value={brief.risk} />}
              {brief.upcoming_bills && <BriefLine label="Upcoming Bills" value={brief.upcoming_bills} />}
              {brief.goal_progress && <BriefLine label="Goal Progress" value={brief.goal_progress} />}
              {brief.recommendation && (
                <div className="rounded-2xl bg-white/5 border border-white/10 p-3 mt-1">
                  <p className="text-[10px] uppercase tracking-widest text-purple">AI Recommendation</p>
                  <p className="text-[13px] mt-1 leading-relaxed">{brief.recommendation}</p>
                </div>
              )}
              <DisclaimerNote className="pt-1" />
            </>
          ) : (
            <p className="text-sm text-muted-foreground">Add a transaction — or load sample data from Settings — to unlock your first briefing.</p>
          )}
        </GlassCard>

      </section>

      {/* Health Ring */}
      <section>
        <GlassCard className="flex items-center gap-4">
          <HealthRing score={healthQ.data?.score ?? 0} size={140} delta={healthDelta} />
          <div className="flex-1">
            <p className="text-[10px] uppercase tracking-widest text-muted-foreground">Financial Health Score</p>
            {healthQ.data ? (
              <p className="text-sm mt-1 leading-relaxed text-foreground/90">
                Your score reflects <strong>{healthQ.data.breakdown.savingsMonths.toFixed(1)} months</strong> of runway, this month's cash flow of <strong>{formatCurrency(healthQ.data.breakdown.net, currency)}</strong>, and progress across <strong>{healthQ.data.breakdown.goalsCount}</strong> goal(s).
              </p>
            ) : (
              <div className="mt-2 space-y-2">
                <Skeleton className="h-4 w-full" />
                <Skeleton className="h-4 w-4/5" />
              </div>
            )}
          </div>
        </GlassCard>
      </section>

      {/* Trends — switchable chart with timeframe */}
      <section className="space-y-3">
        <div className="flex justify-between items-center px-1">
          <SectionLabel>Trends</SectionLabel>
        </div>
        <div className="flex gap-1.5 overflow-x-auto hide-scrollbar -mx-4 px-4">
          {CHART_TABS.map((t) => {
            const on = activeChart === t.key;
            const Icon = t.icon;
            return (
              <button
                key={t.key}
                onClick={() => setActiveChart(t.key)}
                className={`shrink-0 inline-flex items-center gap-1.5 rounded-full px-3 py-1.5 text-[11px] font-medium transition-all ${
                  on ? "bg-gradient-to-br from-electric to-purple text-primary-foreground" : "glass text-muted-foreground hover:text-foreground"
                }`}
              >
                <Icon className="size-3" /> {t.label}
              </button>
            );
          })}
        </div>
        <AuraLineChart
          title={active.title}
          subtitle={active.subtitle}
          data={active.data}
          currency={currency}
          color={active.color}
          format={active.format ?? "currency"}
          timeframe={timeframe}
          onTimeframeChange={setTimeframe}
          emptyLabel="Add transactions to see this trend"
        />
        {activeChart === "income_expense" && (
          <AuraLineChart
            title="Expenses"
            subtitle="Daily rollup"
            data={expenseSeries}
            currency={currency}
            color="var(--destructive)"
            timeframe={timeframe}
            onTimeframeChange={setTimeframe}
          />
        )}
      </section>

      <IntelligencePanel />

      {/* Goals */}
      {(goalsQ.data ?? []).length > 0 && (
        <section className="space-y-3">
          <SectionLabel>Goals</SectionLabel>
          <div className="flex gap-3 overflow-x-auto hide-scrollbar -mx-4 px-4 pb-1">
            {(goalsQ.data ?? []).map((g: any) => {
              const pct = Math.min(100, (Number(g.current_amount) / Number(g.target_amount)) * 100);
              return (
                <div key={g.id} className="glass rounded-2xl p-4 min-w-[220px]">
                  <p className="text-sm font-medium">{g.name}</p>
                  <p className="text-xs text-muted-foreground mt-0.5">{formatCurrency(Number(g.current_amount), currency)} of {formatCurrency(Number(g.target_amount), currency)}</p>
                  <div className="mt-3 h-1.5 rounded-full bg-white/10 overflow-hidden">
                    <div className="h-full bg-gradient-to-r from-electric to-purple transition-all duration-700" style={{ width: `${pct}%` }} />
                  </div>
                </div>
              );
            })}
          </div>
        </section>
      )}

      {/* Recent transactions */}
      <section className="space-y-3">
        <div className="flex justify-between items-center px-1">
          <SectionLabel>Recent activity</SectionLabel>
          <Link to="/transactions" className="text-xs text-electric font-medium">See all</Link>
        </div>
        <div className="glass rounded-3xl divide-y divide-border">
          {[...txs].reverse().slice(0, 5).map((t: any) => (
            <div key={t.id} className="p-4 flex items-center justify-between">
              <div className="flex items-center gap-3">
                <div className="size-9 rounded-full bg-white/5 grid place-items-center text-xs font-medium">
                  {(t.merchant ?? t.category ?? "•").slice(0, 1).toUpperCase()}
                </div>
                <div>
                  <p className="text-sm font-medium">{t.merchant ?? t.category}</p>
                  <p className="text-[11px] text-muted-foreground">{t.category} · {relativeDay(t.occurred_at)}</p>
                </div>
              </div>
              <p className={`text-sm font-medium ${t.type === "income" ? "text-success" : "text-foreground"}`}>
                {t.type === "income" ? "+" : "-"}{formatCurrency(Number(t.amount), currency)}
              </p>
            </div>
          ))}
          {txs.length === 0 && (
            <div className="p-6 text-center text-sm text-muted-foreground">No transactions yet. Tap + to add one — or load sample data in <Link to="/settings" className="text-electric">Settings</Link>.</div>
          )}
        </div>
      </section>

      <Link to="/intelligence" className="glass rounded-2xl p-4 flex items-center gap-3 active:scale-[0.99] transition">
        <div className="size-9 rounded-xl bg-gradient-to-br from-electric to-purple grid place-items-center shrink-0">
          <Sparkles className="size-4 text-primary-foreground" />
        </div>
        <div className="flex-1">
          <p className="text-sm font-medium">AI Intelligence</p>
          <p className="text-[11px] text-muted-foreground">Proactive recommendations, Financial DNA, weekly story</p>
        </div>
        <span className="text-xs text-electric">Open</span>
      </Link>

      <div className="glass rounded-2xl p-4 flex items-start gap-3" style={{ borderColor: "color-mix(in oklab, var(--purple) 30%, transparent)" }}>
        <Bell className="size-4 text-purple mt-0.5 shrink-0" />
        <p className="text-xs text-foreground/90 leading-relaxed">
          <span className="font-semibold text-purple">Heads up:</span>{" "}
          {net === 0
            ? `No activity recorded yet this month. Add a transaction to keep your numbers accurate.`
            : net > 0
              ? `You're ${formatCurrency(net, currency)} ahead this month. Consider sending some to a goal.`
              : `You're ${formatCurrency(Math.abs(net), currency)} over this month. Review your top categories.`}

        </p>
      </div>


      <button
        onClick={() => router.navigate({ to: "/transactions", search: { new: 1 } as any })}
        className="fixed bottom-24 right-6 size-14 rounded-full bg-gradient-to-br from-electric to-purple text-primary-foreground grid place-items-center glow-electric active:scale-95 transition"
        aria-label="Add transaction"
      >
        <Plus className="size-6" strokeWidth={2.5} />
      </button>
    </div>
  );
}

function BriefLine({ label, value, icon }: { label: string; value: string; icon?: "mission" | "opp" | "risk" }) {
  const tone = icon === "mission" ? "text-electric" : icon === "opp" ? "text-success" : icon === "risk" ? "text-warning" : "text-muted-foreground";
  const Icon = icon === "mission" ? Target : icon === "opp" ? TrendingUp : icon === "risk" ? TrendingDown : null;
  return (
    <div className="flex gap-2">
      <div className={`text-[10px] uppercase tracking-widest ${tone} shrink-0 w-24 pt-0.5 flex items-center gap-1`}>
        {Icon && <Icon className="size-3" />} {label}
      </div>
      <p className="text-[13px] leading-relaxed text-foreground/90 flex-1">{value}</p>
    </div>
  );
}

function BriefStat({ label, value, tone }: { label: string; value: string; tone?: "success" | "warn" }) {
  return (
    <div className="rounded-2xl bg-white/5 border border-white/10 p-3">
      <p className="text-[10px] text-muted-foreground uppercase tracking-widest">{label}</p>
      <p className={`text-base font-semibold mt-0.5 tabular-nums ${tone === "success" ? "text-success" : tone === "warn" ? "text-warning" : ""}`}>{value}</p>
    </div>
  );
}
