"use client";

import { useEffect, useMemo, useRef, useState } from "react";
import { AppShell } from "../../components/app-shell";

type ApiResponse<T> = {
  data: T;
  meta: { timestamp: string; version: "v1" };
  error: null | { message: string; code?: string };
};

type Summary = {
  total: string;
  count: number;
  income?: string;
  expense?: string;
  net?: string;
};

type CashflowPoint = {
  month: string;
  income: string;
  expense: string;
  net: string;
};

type MerchantInsight = {
  merchant: string;
  total: string;
  count: number;
};

type Account = {
  id: string;
};

const recentTransactions = [
  {
    date: "Oct 24, 2023",
    description: "Whole Foods Market",
    category: "Groceries",
    account: "Chase Sapphire",
    amount: "-$142.30"
  },
  {
    date: "Oct 23, 2023",
    description: "Apple Subscription",
    category: "Services",
    account: "Apple Card",
    amount: "-$14.99"
  },
  {
    date: "Oct 22, 2023",
    description: "Stripe Payout",
    category: "Income",
    account: "Mercury Business",
    amount: "+$4,200.00"
  },
  {
    date: "Oct 22, 2023",
    description: "Shell Gasoline",
    category: "Transport",
    account: "Chase Sapphire",
    amount: "-$52.12"
  }
];


















import { motion, AnimatePresence } from "framer-motion";

function formatMonthLabel(yyyyMm: string) {
  // "2026-01" -> "Jan 2026"
  const [y, m] = yyyyMm.split("-").map((v) => Number(v));
  const d = new Date(y, (m || 1) - 1, 1);
  return d.toLocaleString(undefined, { month: "short", year: "numeric" });
}

function formatCurrency(n: number) {
  const abs = Math.abs(n);
  const sign = n < 0 ? "-" : "";
  return `${sign}$${abs.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
}



export function CashflowChart({
  data,
  loading
}: {
  data: CashflowPoint[];
  loading: boolean;
}) {
  const wrapRef = useRef<HTMLDivElement | null>(null);
  const [activeIndex, setActiveIndex] = useState<number | null>(null);

  const parsed = useMemo(() => {
    return (data ?? []).map((d) => {
      const income = Number.parseFloat(d.income ?? "0") || 0;
      const expense = Number.parseFloat(d.expense ?? "0") || 0;
      const net = Number.parseFloat(d.net ?? "0") || 0;
      return {
        ...d,
        income,
        expense,
        net,
        label: formatMonthLabel(d.month)
      };
    });
  }, [data]);

  const chart = useMemo(() => {
    const W = 600;
    const H = 240;
    const PAD_L = 28;
    const PAD_R = 18;
    const PAD_T = 18;
    const PAD_B = 30;

    const innerW = W - PAD_L - PAD_R;
    const innerH = H - PAD_T - PAD_B;

    if (!parsed.length) {
      return {
        W,
        H,
        PAD_L,
        PAD_R,
        PAD_T,
        PAD_B,
        innerW,
        innerH,
        yZero: PAD_T + innerH / 2,
        points: [] as { x: number; y: number; net: number; income: number; expense: number; label: string; month: string }[],
        lineD: "",
        areaD: "",
        bars: [] as { x: number; w: number; yIncome: number; hIncome: number; yExpense: number; hExpense: number }[],
        ticks: [] as { y: number; value: number }[]
      };
    }

    const nets = parsed.map((d) => d.net);

    // symmetric range around 0 so negatives/positives are balanced visually
    const maxAbs = Math.max(1, ...nets.map((v) => Math.abs(v)));
    const yMax = maxAbs;
    const yMin = -maxAbs;

    const xStep = parsed.length === 1 ? 0 : innerW / (parsed.length - 1);

    const yScale = (v: number) => {
      // map yMax -> PAD_T, yMin -> PAD_T+innerH
      const t = (v - yMax) / (yMin - yMax);
      return PAD_T + t * innerH;
    };

    const yZero = yScale(0);

    const points = parsed.map((d, i) => {
      const x = PAD_L + xStep * i;
      const y = yScale(d.net);
      return { x, y, net: d.net, income: d.income, expense: d.expense, label: d.label, month: d.month };
    });

    const lineD = points.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`).join(" ");

    // area fill to the zero baseline
    const areaD = [
      `M ${points[0].x} ${yZero}`,
      ...points.map((p) => `L ${p.x} ${p.y}`),
      `L ${points[points.length - 1].x} ${yZero}`,
      "Z"
    ].join(" ");

    // income/expense bars (scaled using max of income/expense)
    const maxBar = Math.max(
      1,
      ...parsed.map((d) => Math.max(Math.abs(d.income), Math.abs(d.expense)))
    );
    const barScale = (v: number) => (Math.abs(v) / maxBar) * (innerH * 0.42);

    const barBand = innerW / parsed.length;
    const barW = Math.max(10, Math.min(22, barBand * 0.45));

    const bars = parsed.map((d, i) => {
      const cx = PAD_L + barBand * i + barBand / 2;
      const x = cx - barW / 2;

      const hIncome = barScale(d.income);
      const hExpense = barScale(d.expense);

      // draw both as upward bars from the bottom area
      const baseY = PAD_T + innerH; // bottom
      const yIncome = baseY - hIncome;
      const yExpense = baseY - hExpense;

      return { x, w: barW, yIncome, hIncome, yExpense, hExpense };
    });

    // y-axis ticks for context (3 ticks)
    const ticks = [-yMax, 0, yMax].map((v) => ({ value: v, y: yScale(v) }));

    return { W, H, PAD_L, PAD_R, PAD_T, PAD_B, innerW, innerH, yZero, points, lineD, areaD, bars, ticks };
  }, [parsed]);

  const active = activeIndex === null ? null : parsed[activeIndex];

  function pickNearestIndex(clientX: number) {
    if (!wrapRef.current || !chart.points.length) return null;
    const rect = wrapRef.current.getBoundingClientRect();

    // convert clientX to svg X (0..W)
    const x = ((clientX - rect.left) / rect.width) * chart.W;
    let best = 0;
    let bestDist = Infinity;

    for (let i = 0; i < chart.points.length; i++) {
      const d = Math.abs(chart.points[i].x - x);
      if (d < bestDist) {
        bestDist = d;
        best = i;
      }
    }
    return best;
  }

  return (
    <div
      ref={wrapRef}
      className="mt-4 rounded-xl border border-border p-4 bg-background/50 relative overflow-hidden"
      style={{
        backgroundImage:
          "linear-gradient(rgba(49, 98, 99, 0.06) 1px, transparent 1px), linear-gradient(90deg, rgba(49, 98, 99, 0.06) 1px, transparent 1px)",
        backgroundSize: "40px 40px"
      }}
      onMouseLeave={() => setActiveIndex(null)}
      onMouseMove={(e) => {
        const idx = pickNearestIndex(e.clientX);
        setActiveIndex(idx);
      }}
    >
      <svg viewBox={`0 0 ${chart.W} ${chart.H}`} className="h-56 w-full">
        <defs>
          <linearGradient id="netFill" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor="var(--primary)" stopOpacity="0.22" />
            <stop offset="100%" stopColor="var(--primary)" stopOpacity="0.02" />
          </linearGradient>

          <linearGradient id="barsIncome" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor="var(--primary)" stopOpacity="0.55" />
            <stop offset="100%" stopColor="var(--primary)" stopOpacity="0.10" />
          </linearGradient>

          <linearGradient id="barsExpense" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor="rgb(239 68 68)" stopOpacity="0.55" />
            <stop offset="100%" stopColor="rgb(239 68 68)" stopOpacity="0.10" />
          </linearGradient>
        </defs>

        {loading ? (
          <rect
            x="0"
            y="0"
            width={chart.W}
            height={chart.H}
            fill="currentColor"
            className="text-secondary/30 animate-pulse"
          />
        ) : !chart.points.length ? (
          <text x={chart.W / 2} y={chart.H / 2} textAnchor="middle" fill="currentColor" className="text-xs text-muted-foreground">
            No cash flow data available
          </text>
        ) : (
          <>
            {/* y ticks */}
            {chart.ticks.map((t) => (
              <g key={t.value}>
                <line
                  x1={chart.PAD_L}
                  x2={chart.W - chart.PAD_R}
                  y1={t.y}
                  y2={t.y}
                  stroke="currentColor"
                  strokeOpacity={t.value === 0 ? 0.18 : 0.08}
                />
                <text
                  x={6}
                  y={t.y + 4}
                  fill="currentColor"
                  className="text-[10px] text-muted-foreground"
                >
                  {formatCurrency(t.value)}
                </text>
              </g>
            ))}

            {/* income/expense bars (bottom) */}
            {chart.bars.map((b, i) => (
              <g key={i}>
                <motion.rect
                  x={b.x - 6}
                  y={b.yExpense}
                  width={b.w}
                  height={b.hExpense}
                  rx="6"
                  fill="url(#barsExpense)"
                  initial={{ height: 0, y: chart.PAD_T + chart.innerH }}
                  animate={{ height: b.hExpense, y: b.yExpense }}
                  transition={{ duration: 0.55, delay: i * 0.04, ease: [0.2, 0.8, 0.2, 1] }}
                  opacity={0.9}
                />
                <motion.rect
                  x={b.x + 6}
                  y={b.yIncome}
                  width={b.w}
                  height={b.hIncome}
                  rx="6"
                  fill="url(#barsIncome)"
                  initial={{ height: 0, y: chart.PAD_T + chart.innerH }}
                  animate={{ height: b.hIncome, y: b.yIncome }}
                  transition={{ duration: 0.55, delay: i * 0.04 + 0.06, ease: [0.2, 0.8, 0.2, 1] }}
                  opacity={0.9}
                />
              </g>
            ))}

            {/* net area */}
            <motion.path
              d={chart.areaD}
              fill="url(#netFill)"
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              transition={{ duration: 0.45 }}
            />

            {/* net line */}
            <motion.path
              d={chart.lineD}
              fill="none"
              stroke="var(--primary)"
              strokeWidth="3"
              strokeLinecap="round"
              strokeLinejoin="round"
              initial={{ pathLength: 0 }}
              animate={{ pathLength: 1 }}
              transition={{ duration: 0.9, ease: [0.2, 0.8, 0.2, 1] }}
            />

            {/* points */}
            {chart.points.map((p, i) => {
              const isActive = i === activeIndex;
              return (
                <g key={i}>
                  <motion.circle
                    cx={p.x}
                    cy={p.y}
                    r={isActive ? 6 : 4}
                    fill="var(--primary)"
                    initial={{ scale: 0 }}
                    animate={{ scale: 1 }}
                    transition={{ duration: 0.25, delay: i * 0.03 }}
                    opacity={isActive ? 1 : 0.75}
                  />
                  {/* subtle glow ring on active */}
                  {isActive ? (
                    <circle cx={p.x} cy={p.y} r="12" fill="var(--primary)" opacity="0.10" />
                  ) : null}
                </g>
              );
            })}

            {/* hover crosshair */}
            {activeIndex !== null && chart.points[activeIndex] ? (
              <g>
                <line
                  x1={chart.points[activeIndex].x}
                  x2={chart.points[activeIndex].x}
                  y1={chart.PAD_T}
                  y2={chart.PAD_T + chart.innerH}
                  stroke="currentColor"
                  strokeOpacity="0.15"
                  strokeDasharray="4 4"
                />
              </g>
            ) : null}

            {/* x labels (every point; small) */}
            {chart.points.map((p, i) => (
              <text
                key={i}
                x={p.x}
                y={chart.H - 10}
                textAnchor="middle"
                fill="currentColor"
                className="text-[10px] text-muted-foreground"
                opacity={i % 2 === 0 ? 0.9 : 0.55}
              >
                {parsed[i]?.month ?? ""}
              </text>
            ))}
          </>
        )}
      </svg>

      {/* Tooltip */}
      <AnimatePresence>
        {!loading && active && activeIndex !== null ? (
          <motion.div
            key="tooltip"
            initial={{ opacity: 0, y: 6, scale: 0.98 }}
            animate={{ opacity: 1, y: 0, scale: 1 }}
            exit={{ opacity: 0, y: 6, scale: 0.98 }}
            transition={{ duration: 0.18 }}
            className="absolute top-3 right-3 rounded-xl border border-border bg-background/90 backdrop-blur px-3 py-2 shadow-sm"
          >
            <div className="text-xs font-semibold text-foreground">{active.label}</div>
            <div className="mt-1 grid gap-1 text-[11px] text-muted-foreground">
              <div className="flex items-center justify-between gap-6">
                <span>Income</span>
                <span className="font-semibold text-foreground">{formatCurrency(active.income)}</span>
              </div>
              <div className="flex items-center justify-between gap-6">
                <span>Expense</span>
                <span className="font-semibold text-foreground">{formatCurrency(active.expense)}</span>
              </div>
              <div className="h-px bg-border my-1" />
              <div className="flex items-center justify-between gap-6">
                <span>Net</span>
                <span className={`font-bold ${active.net < 0 ? "text-red-500" : "text-primary"}`}>
                  {formatCurrency(active.net)}
                </span>
              </div>
            </div>
          </motion.div>
        ) : null}
      </AnimatePresence>

      {/* Legend */}
      {!loading && parsed.length ? (
        <div className="mt-2 flex flex-wrap items-center gap-2 text-[11px] text-muted-foreground">
          <span className="inline-flex items-center gap-2 rounded-full border border-border bg-secondary/40 px-2 py-1">
            <span className="h-2 w-2 rounded-full bg-primary" />
            Net (line)
          </span>
          <span className="inline-flex items-center gap-2 rounded-full border border-border bg-secondary/40 px-2 py-1">
            <span className="h-2 w-2 rounded-full bg-red-500" />
            Expense (bar)
          </span>
          <span className="inline-flex items-center gap-2 rounded-full border border-border bg-secondary/40 px-2 py-1">
            <span className="h-2 w-2 rounded-full bg-primary/70" />
            Income (bar)
          </span>
        </div>
      ) : null}
    </div>
  );
}







export default function AppHomePage() {
  const [summary, setSummary] = useState<Summary | null>(null);
  const [cashflow, setCashflow] = useState<CashflowPoint[]>([]);
  const [merchants, setMerchants] = useState<MerchantInsight[]>([]);
  const [accountCount, setAccountCount] = useState<number | null>(null);

  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const userId = localStorage.getItem("ledgerone_user_id");
    if (!userId) {
      setLoading(false);
      return;
    }
    const query = `?user_id=${encodeURIComponent(userId)}`;

    Promise.all([
      fetch(`/api/transactions/summary${query}`).then((res) => res.json()),
      fetch(`/api/transactions/cashflow${query}&months=6`).then((res) => res.json()),
      fetch(`/api/transactions/merchants${query}&limit=5`).then((res) => res.json()),
      fetch(`/api/accounts${query}`).then((res) => res.json())
    ])
      .then(([summaryRes, cashflowRes, merchantsRes, accountsRes]) => {
        if (!summaryRes.error) setSummary(summaryRes.data);
        if (!cashflowRes.error) setCashflow(cashflowRes.data);
        if (!merchantsRes.error) setMerchants(merchantsRes.data);
        if (!accountsRes.error) setAccountCount(accountsRes.data.length);
      })
      .catch(() => undefined)
      .finally(() => setLoading(false));
  }, []);

  const cashflowPath = useMemo(() => {
    if (!cashflow.length) {
      return "";
    }
    const values = cashflow.map((item) => Number.parseFloat(item.net));
    const max = Math.max(...values.map((v) => Math.abs(v)), 1);
    const stepX = 460 / Math.max(values.length - 1, 1);
    return values
      .map((value, index) => {
        const x = 10 + stepX * index;
        const y = 170 - (value / max) * 120;
        return `${index === 0 ? "M" : "L"} ${x} ${y}`;
      })
      .join(" ");
  }, [cashflow]);

  return (
    <AppShell title="Dashboard" subtitle="Performance overview and live account health.">
      <section className="flex flex-wrap items-center gap-3 text-xs text-muted-foreground">
        <span className="flex items-center gap-2 px-4 py-2 rounded-full bg-secondary/50 border border-border font-medium">
          <span className="h-2 w-2 rounded-full bg-primary" />
          Last 30 days
        </span>
        <span className="flex items-center gap-2 px-4 py-2 rounded-full bg-secondary/50 border border-border font-medium">
          <span className="h-2 w-2 rounded-full bg-primary" />
          All categories
        </span>
        <span className="flex items-center gap-2 px-4 py-2 rounded-full bg-secondary/50 border border-border font-medium">
          <span className="h-2 w-2 rounded-full bg-primary" />
          Combined accounts
        </span>
        <span className="ml-auto hidden text-xs text-muted-foreground lg:block">Auto sync enabled</span>
      </section>

      <section className="mt-6 grid gap-4 md:grid-cols-2 xl:grid-cols-4">
        <div className="glass-panel p-5 rounded-2xl shadow-sm">
          <p className="text-xs uppercase tracking-[0.2em] text-muted-foreground font-semibold">Income (30d)</p>
          <div className="mt-3 flex items-baseline justify-between">
            <p className="text-2xl font-bold text-foreground">
              {summary?.income ? `$${summary.income}` : "$0.00"}
            </p>
            <span className="text-xs font-medium text-primary bg-primary/10 px-2 py-1 rounded-full">Inflow</span>
          </div>
          <p className="mt-2 text-xs text-muted-foreground">Deposits and credits</p>
        </div>
        <div className="glass-panel p-5 rounded-2xl shadow-sm">
          <p className="text-xs uppercase tracking-[0.2em] text-muted-foreground font-semibold">Expenses (30d)</p>
          <div className="mt-3 flex items-baseline justify-between">
            <p className="text-2xl font-bold text-foreground">
              {summary?.expense ? `$${summary.expense}` : "$0.00"}
            </p>
            <span className="text-xs font-medium text-red-500 bg-red-500/10 px-2 py-1 rounded-full">Outflow</span>
          </div>
          <p className="mt-2 text-xs text-muted-foreground">Bills and spending</p>
        </div>
        <div className="glass-panel p-5 rounded-2xl shadow-sm">
          <p className="text-xs uppercase tracking-[0.2em] text-muted-foreground font-semibold">Net cash flow</p>
          <div className="mt-3 flex items-baseline justify-between">
            <p className="text-2xl font-bold text-foreground">
              {summary?.net ? `$${summary.net}` : "$0.00"}
            </p>
            <span className="text-xs font-medium text-primary bg-primary/10 px-2 py-1 rounded-full">30d</span>
          </div>
          <p className="mt-2 text-xs text-muted-foreground">
            {summary ? `${summary.count} transactions` : "No data yet"}
          </p>
        </div>
        <div className="glass-panel p-5 rounded-2xl shadow-sm">
          <p className="text-xs uppercase tracking-[0.2em] text-muted-foreground font-semibold">Active accounts</p>
          <div className="mt-3 flex items-baseline justify-between">
            <p className="text-2xl font-bold text-foreground">
              {accountCount !== null ? accountCount : 0}
            </p>
            <span className="text-xs font-medium text-primary bg-primary/10 px-2 py-1 rounded-full">Linked</span>
          </div>
          <p className="mt-2 text-xs text-muted-foreground">Bank + card connections</p>
        </div>
      </section>

      <section className="mt-6 grid gap-4 xl:grid-cols-[2fr_1fr]">
        <div className="glass-panel p-6 rounded-2xl shadow-sm">
          <div className="flex items-center justify-between">
            <div>
              <p className="text-sm font-bold text-foreground">Monthly Cash-Flow</p>
              <p className="text-xs text-muted-foreground">Net flow over last 6 months</p>
            </div>
            <div className="text-xs text-muted-foreground font-medium">Income vs expense</div>
          </div>
          <CashflowChart data={cashflow} loading={loading} />

          <div className="mt-4 grid gap-2 text-xs text-muted-foreground md:grid-cols-3">
            {cashflow.map((item) => (
              <div key={item.month} className="flex items-center justify-between">
                <span className="font-medium">{item.month}</span>
                <span className="text-foreground font-bold">${item.net}</span>
              </div>
            ))}
          </div>
        </div>

        <div className="glass-panel p-6 rounded-2xl shadow-sm">
          <div className="flex items-center justify-between">
            <div>
              <p className="text-sm font-bold text-foreground">Top Merchants</p>
              <p className="text-xs text-muted-foreground">Highest spend by merchant</p>
            </div>
          </div>
          <div className="mt-6 space-y-4 text-xs">
            {merchants.length ? (
              merchants.map((merchant) => (
                <div key={merchant.merchant} className="flex items-center justify-between border-b border-border pb-2 last:border-0 last:pb-0">
                  <div>
                    <p className="text-sm font-medium text-foreground">{merchant.merchant}</p>
                    <p className="text-xs text-muted-foreground">
                      {merchant.count} transaction{merchant.count === 1 ? "" : "s"}
                    </p>
                  </div>
                  <span className="text-sm font-bold text-foreground">${merchant.total}</span>
                </div>
              ))
            ) : (
              <p className="text-sm text-muted-foreground">No merchant insights yet.</p>
            )}
          </div>
        </div>
      </section>

      <section className="mt-6 glass-panel p-6 rounded-2xl shadow-sm">
        <div className="flex items-center justify-between">
          <h2 className="text-sm font-bold text-foreground">Recent Transactions</h2>
          <span className="text-xs font-medium text-primary cursor-pointer hover:underline">View all records</span>
        </div>
        <div className="mt-4 overflow-x-auto">
          <table className="w-full text-left text-xs text-muted-foreground">
            <thead className="text-[0.65rem] uppercase tracking-[0.2em] text-muted-foreground font-semibold">
              <tr className="border-b border-border">
                <th className="pb-3 pl-2">Date</th>
                <th className="pb-3">Description</th>
                <th className="pb-3">Category</th>
                <th className="pb-3">Account</th>
                <th className="pb-3 pr-2 text-right">Amount</th>
              </tr>
            </thead>
            <tbody>
              {recentTransactions.map((tx) => (
                <tr key={`${tx.date}-${tx.description}`} className="border-b border-border hover:bg-secondary/30 transition-colors">
                  <td className="py-3 pl-2 font-medium">{tx.date}</td>
                  <td className="py-3 text-foreground font-medium">{tx.description}</td>
                  <td className="py-3">
                    <span className="inline-flex items-center rounded-full bg-secondary px-2 py-0.5 text-xs font-medium text-foreground">
                      {tx.category}
                    </span>
                  </td>
                  <td className="py-3">{tx.account}</td>
                  <td className={`py-3 pr-2 text-right font-bold ${tx.amount.startsWith('+') ? 'text-primary' : 'text-foreground'}`}>
                    {tx.amount}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </section>
    </AppShell>
  );
}
