"use client";

import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { formatCents } from "@/lib/utils/format";
import {
  TrendingUp, TrendingDown, Wallet, ChevronDown, ChevronUp,
  RefreshCw, Landmark, BarChart2,
} from "lucide-react";
import { CategoryIcon } from "@/components/ui/category-icon";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/utils";
import {
  AreaChart, Area, BarChart, Bar, XAxis, YAxis,
  CartesianGrid, Tooltip, ResponsiveContainer, Legend,
} from "recharts";

// ── Types (mirror API) ───────────────────────────────────────
type ProjectionSource = "recurring" | "loan" | "historical_avg";

interface CategoryLine {
  key: string;
  name: string;
  icon?: string;
  color?: string;
  type: "INCOME" | "EXPENSE";
  source: ProjectionSource;
  amountCents: number;
}

interface MonthData {
  month: string;
  label: string;
  totalIncomeCents: number;
  totalExpenseCents: number;
  cashFlowCents: number;
  lines: CategoryLine[];
}

interface CategorySummary {
  key: string;
  name: string;
  icon?: string;
  color?: string;
  type: "INCOME" | "EXPENSE";
  source: ProjectionSource;
  avgMonthlyCents: number;
  totalCents: number;
}

interface ProjectionData {
  monthly: MonthData[];
  categorySummaries: CategorySummary[];
  summary: {
    totalProjectedIncomeCents: number;
    totalProjectedExpensesCents: number;
    totalProjectedCashFlowCents: number;
    avgMonthlyIncomeCents: number;
    avgMonthlyExpenseCents: number;
    avgMonthlyCashFlowCents: number;
  };
}

// ── Helpers ──────────────────────────────────────────────────
const SOURCE_BADGE: Record<ProjectionSource, { label: string; cls: string }> = {
  recurring:     { label: "Recurring",   cls: "bg-blue-500/15 text-blue-400 border-blue-500/30"   },
  loan:          { label: "Loan EMI",    cls: "bg-amber-500/15 text-amber-400 border-amber-500/30" },
  historical_avg:{ label: "Avg (3mo)",   cls: "bg-slate-600/50 text-slate-400 border-slate-600"    },
};

const SOURCE_ICON: Record<ProjectionSource, React.ReactNode> = {
  recurring:      <RefreshCw className="h-3 w-3" />,
  loan:           <Landmark  className="h-3 w-3" />,
  historical_avg: <BarChart2 className="h-3 w-3" />,
};

// Merge lines with the same key+source into one row per category per month
function mergeLines(lines: CategoryLine[]): CategoryLine[] {
  const map = new Map<string, CategoryLine>();
  for (const l of lines) {
    const k = `${l.key}__${l.source}`;
    const prev = map.get(k);
    if (prev) {
      map.set(k, { ...prev, amountCents: prev.amountCents + l.amountCents });
    } else {
      map.set(k, { ...l });
    }
  }
  return Array.from(map.values());
}

function CentsTooltip({ active, payload, label }: {
  active?: boolean;
  payload?: { name: string; value: number; color: string }[];
  label?: string;
}) {
  if (!active || !payload?.length) return null;
  return (
    <div className="bg-slate-800 border border-slate-700 rounded-lg p-3 text-xs space-y-1 shadow-xl">
      <p className="text-slate-400 font-medium mb-1.5">{label}</p>
      {payload.map((p) => (
        <div key={p.name} className="flex items-center gap-2">
          <span className="w-2 h-2 rounded-full shrink-0" style={{ backgroundColor: p.color }} />
          <span className="text-slate-300">{p.name}:</span>
          <span className="font-semibold text-white">{formatCents(p.value)}</span>
        </div>
      ))}
    </div>
  );
}

// ── Category card ────────────────────────────────────────────
function CategoryRow({ cat, maxCents }: { cat: CategorySummary; maxCents: number }) {
  const pct = maxCents > 0 ? Math.round((cat.avgMonthlyCents / maxCents) * 100) : 0;
  const isIncome = cat.type === "INCOME";

  return (
    <div className="space-y-1.5 py-2 border-b border-slate-700/40 last:border-0">
      <div className="flex items-center justify-between gap-2">
        <div className="flex items-center gap-2 min-w-0">
          {cat.icon && <CategoryIcon icon={cat.icon} color={cat.color} className="h-4 w-4 shrink-0" />}
          <span className="text-sm text-slate-200 truncate">{cat.name}</span>
          <Badge className={cn("text-[10px] px-1.5 py-0 h-4 border shrink-0", SOURCE_BADGE[cat.source].cls)}>
            <span className="flex items-center gap-1">
              {SOURCE_ICON[cat.source]}
              {SOURCE_BADGE[cat.source].label}
            </span>
          </Badge>
        </div>
        <div className="text-right shrink-0">
          <p className={cn("text-sm font-semibold", isIncome ? "text-emerald-400" : "text-red-400")}>
            {formatCents(cat.avgMonthlyCents)}<span className="text-slate-500 font-normal text-xs">/mo</span>
          </p>
        </div>
      </div>
      {/* Progress bar showing relative size */}
      <div className="h-1 w-full rounded-full bg-slate-700/50 overflow-hidden">
        <div
          className={cn("h-full rounded-full transition-all", isIncome ? "bg-emerald-500/60" : "bg-red-500/60")}
          style={{ width: `${pct}%` }}
        />
      </div>
    </div>
  );
}

// ── Month row (expandable) ───────────────────────────────────
function MonthRow({ month }: { month: MonthData }) {
  const [open, setOpen] = useState(false);
  const positive = month.cashFlowCents >= 0;
  const merged = mergeLines(month.lines);
  const income  = merged.filter((l) => l.type === "INCOME").sort((a, b) => b.amountCents - a.amountCents);
  const expense = merged.filter((l) => l.type === "EXPENSE").sort((a, b) => b.amountCents - a.amountCents);

  return (
    <Card className="bg-slate-800/50 border-slate-700/50">
      <CardContent className="p-0">
        <button
          onClick={() => setOpen((v) => !v)}
          className="w-full flex items-center justify-between px-4 py-3 hover:bg-slate-700/20 transition-colors rounded-xl text-left"
        >
          <div className="flex items-center gap-4">
            <span className="text-sm font-semibold text-white w-20 shrink-0">{month.label}</span>
            <div className="hidden sm:flex gap-4 text-xs">
              <span className="text-emerald-400">+{formatCents(month.totalIncomeCents)}</span>
              <span className="text-slate-600">·</span>
              <span className="text-red-400">−{formatCents(month.totalExpenseCents)}</span>
            </div>
          </div>
          <div className="flex items-center gap-2">
            <span className={cn("text-sm font-bold", positive ? "text-emerald-400" : "text-red-400")}>
              {positive ? "+" : "−"}{formatCents(Math.abs(month.cashFlowCents))}
            </span>
            {open ? <ChevronUp className="h-4 w-4 text-slate-500" /> : <ChevronDown className="h-4 w-4 text-slate-500" />}
          </div>
        </button>

        {/* Mobile amounts row */}
        <div className="flex sm:hidden gap-3 px-4 pb-2 text-xs">
          <span className="text-emerald-400">Income: {formatCents(month.totalIncomeCents)}</span>
          <span className="text-red-400">Exp: {formatCents(month.totalExpenseCents)}</span>
        </div>

        {open && (
          <div className="border-t border-slate-700/50 px-4 pb-4 pt-3 grid grid-cols-1 sm:grid-cols-2 gap-6">
            {/* Income */}
            <div>
              <p className="text-xs font-semibold text-slate-400 uppercase tracking-wide mb-2 flex items-center gap-1">
                <TrendingUp className="h-3 w-3 text-emerald-400" /> Income
              </p>
              {income.length === 0 ? (
                <p className="text-xs text-slate-600">No income projected</p>
              ) : income.map((l, i) => (
                <div key={i} className="flex items-center justify-between py-1.5 border-b border-slate-700/30 last:border-0">
                  <div className="flex items-center gap-1.5 min-w-0 text-xs">
                    {l.icon && <span>{l.icon}</span>}
                    <span className={cn("flex items-center gap-1 shrink-0", SOURCE_BADGE[l.source].cls.split(" ")[1])}>
                      {SOURCE_ICON[l.source]}
                    </span>
                    <span className="text-slate-300 truncate">{l.name}</span>
                  </div>
                  <span className="text-emerald-400 text-xs font-mono ml-2 shrink-0">+{formatCents(l.amountCents)}</span>
                </div>
              ))}
              <div className="mt-2 pt-2 border-t border-slate-700/50 flex justify-between text-xs">
                <span className="text-slate-500">Total income</span>
                <span className="text-emerald-400 font-semibold">{formatCents(month.totalIncomeCents)}</span>
              </div>
            </div>

            {/* Expenses */}
            <div>
              <p className="text-xs font-semibold text-slate-400 uppercase tracking-wide mb-2 flex items-center gap-1">
                <TrendingDown className="h-3 w-3 text-red-400" /> Expenses
              </p>
              {expense.length === 0 ? (
                <p className="text-xs text-slate-600">No expenses projected</p>
              ) : expense.map((l, i) => (
                <div key={i} className="flex items-center justify-between py-1.5 border-b border-slate-700/30 last:border-0">
                  <div className="flex items-center gap-1.5 min-w-0 text-xs">
                    {l.icon && <span>{l.icon}</span>}
                    <span className={cn("flex items-center gap-1 shrink-0", SOURCE_BADGE[l.source].cls.split(" ")[1])}>
                      {SOURCE_ICON[l.source]}
                    </span>
                    <span className="text-slate-300 truncate">{l.name}</span>
                  </div>
                  <span className="text-red-400 text-xs font-mono ml-2 shrink-0">−{formatCents(l.amountCents)}</span>
                </div>
              ))}
              <div className="mt-2 pt-2 border-t border-slate-700/50 flex justify-between text-xs">
                <span className="text-slate-500">Total expenses</span>
                <span className="text-red-400 font-semibold">{formatCents(month.totalExpenseCents)}</span>
              </div>
            </div>
          </div>
        )}
      </CardContent>
    </Card>
  );
}

// ── Page ────────────────────────────────────────────────────
const PERIOD_OPTIONS = [
  { label: "3 mo",  value: 3  },
  { label: "6 mo",  value: 6  },
  { label: "12 mo", value: 12 },
];

// Palette for stacked chart categories
const CAT_COLORS = [
  "#10b981","#3b82f6","#f59e0b","#8b5cf6","#ec4899",
  "#14b8a6","#f97316","#6366f1","#84cc16","#06b6d4",
];

export default function ProjectionsPage() {
  const [months, setMonths] = useState(6);

  const { data, isLoading } = useQuery<ProjectionData>({
    queryKey: ["projections", months],
    queryFn: async () => {
      const res = await fetch(`/api/projections?months=${months}`);
      if (!res.ok) throw new Error("Failed to load projections");
      return res.json();
    },
  });

  const s = data?.summary;
  const cashFlowPositive = (s?.totalProjectedCashFlowCents ?? 0) >= 0;

  // Build area chart data (monthly totals)
  const areaData = (data?.monthly ?? []).map((m) => ({
    month:   m.label,
    Income:  Math.round(m.totalIncomeCents   / 100),
    Expense: Math.round(m.totalExpenseCents  / 100),
    "Cash Flow": Math.round(m.cashFlowCents  / 100),
  }));

  // Category summaries split by type
  const incomeCats  = (data?.categorySummaries ?? [])
    .filter((c) => c.type === "INCOME")
    .sort((a, b) => b.avgMonthlyCents - a.avgMonthlyCents);
  const expenseCats = (data?.categorySummaries ?? [])
    .filter((c) => c.type === "EXPENSE")
    .sort((a, b) => b.avgMonthlyCents - a.avgMonthlyCents);

  const maxIncomeCents  = incomeCats[0]?.avgMonthlyCents  ?? 1;
  const maxExpenseCents = expenseCats[0]?.avgMonthlyCents ?? 1;

  // Build stacked bar data for expense categories
  const topExpCats  = expenseCats.slice(0, 6);
  const stackedData = (data?.monthly ?? []).map((m) => {
    const row: Record<string, string | number> = { month: m.label };
    for (const cat of topExpCats) {
      const total = mergeLines(m.lines.filter((l) => l.key === cat.key && l.type === "EXPENSE"))
        .reduce((s, l) => s + l.amountCents, 0);
      row[cat.name] = Math.round(total / 100);
    }
    return row;
  });

  return (
    <div className="space-y-6 max-w-6xl">
      {/* Header */}
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
        <div>
          <h1 className="text-2xl font-bold text-white">Income & Expense Projections</h1>
          <p className="text-slate-400 text-sm mt-0.5">
            Category-by-category forecast — recurring, loan EMIs, and 3-month averages
          </p>
        </div>
        <div className="flex gap-1 bg-slate-800 rounded-lg p-1 border border-slate-700 self-start">
          {PERIOD_OPTIONS.map((opt) => (
            <button
              key={opt.value}
              onClick={() => setMonths(opt.value)}
              className={cn(
                "px-3 py-1.5 rounded-md text-sm font-medium transition-colors",
                months === opt.value ? "bg-emerald-600 text-white" : "text-slate-400 hover:text-slate-200"
              )}
            >
              {opt.label}
            </button>
          ))}
        </div>
      </div>

      {/* Summary cards */}
      <div className="grid grid-cols-2 sm:grid-cols-3 gap-3">
        {[
          {
            label: "Projected Income",
            total: s?.totalProjectedIncomeCents ?? 0,
            avg:   s?.avgMonthlyIncomeCents ?? 0,
            icon: TrendingUp, iconBg: "bg-emerald-500/10", iconClr: "text-emerald-400", valClr: "text-emerald-400",
          },
          {
            label: "Projected Expenses",
            total: s?.totalProjectedExpensesCents ?? 0,
            avg:   s?.avgMonthlyExpenseCents ?? 0,
            icon: TrendingDown, iconBg: "bg-red-500/10", iconClr: "text-red-400", valClr: "text-red-400",
          },
          {
            label: "Net Cash Flow",
            total: Math.abs(s?.totalProjectedCashFlowCents ?? 0),
            avg:   Math.abs(s?.avgMonthlyCashFlowCents ?? 0),
            prefix: cashFlowPositive ? "+" : "−",
            icon: Wallet,
            iconBg:  cashFlowPositive ? "bg-blue-500/10"    : "bg-orange-500/10",
            iconClr: cashFlowPositive ? "text-blue-400"     : "text-orange-400",
            valClr:  cashFlowPositive ? "text-blue-400"     : "text-orange-400",
          },
        ].map((stat) => (
          <Card key={stat.label} className="bg-slate-800/50 border-slate-700/50 last:col-span-2 sm:last:col-span-1">
            <CardContent className="p-4">
              <div className="flex items-center justify-between mb-2">
                <p className="text-xs text-slate-400">{stat.label}</p>
                <div className={cn("rounded-lg p-1.5", stat.iconBg)}>
                  <stat.icon className={cn("h-3.5 w-3.5", stat.iconClr)} />
                </div>
              </div>
              {isLoading ? (
                <div className="h-6 w-28 bg-slate-700/50 rounded animate-pulse" />
              ) : (
                <>
                  <p className={cn("text-xl font-bold", stat.valClr)}>
                    {stat.prefix ?? ""}{formatCents(stat.total)}
                  </p>
                  <p className="text-xs text-slate-500 mt-0.5">{stat.prefix ?? ""}{formatCents(stat.avg)} avg/month</p>
                </>
              )}
            </CardContent>
          </Card>
        ))}
      </div>

      {/* Charts row */}
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
        {/* Area chart — income vs expenses timeline */}
        <Card className="bg-slate-800/50 border-slate-700/50">
          <CardHeader className="pb-1">
            <CardTitle className="text-white text-sm">Monthly Cash Flow</CardTitle>
          </CardHeader>
          <CardContent>
            {isLoading ? (
              <div className="h-48 bg-slate-700/20 rounded-lg animate-pulse" />
            ) : (
              <ResponsiveContainer width="100%" height={200}>
                <AreaChart data={areaData} margin={{ top: 4, right: 4, left: 0, bottom: 0 }}>
                  <defs>
                    <linearGradient id="incG" x1="0" y1="0" x2="0" y2="1">
                      <stop offset="5%"  stopColor="#10b981" stopOpacity={0.25} />
                      <stop offset="95%" stopColor="#10b981" stopOpacity={0.02} />
                    </linearGradient>
                    <linearGradient id="expG" x1="0" y1="0" x2="0" y2="1">
                      <stop offset="5%"  stopColor="#f87171" stopOpacity={0.25} />
                      <stop offset="95%" stopColor="#f87171" stopOpacity={0.02} />
                    </linearGradient>
                  </defs>
                  <CartesianGrid strokeDasharray="3 3" stroke="#334155" vertical={false} />
                  <XAxis dataKey="month" tick={{ fill: "#94a3b8", fontSize: 10 }} axisLine={false} tickLine={false} />
                  <YAxis tickFormatter={(v) => `$${(v/1000).toFixed(0)}k`} tick={{ fill: "#94a3b8", fontSize: 10 }} axisLine={false} tickLine={false} width={40} />
                  <Tooltip content={<CentsTooltip />} />
                  <Legend iconType="circle" iconSize={7} wrapperStyle={{ fontSize: 10, color: "#94a3b8", paddingTop: 6 }} />
                  <Area type="monotone" dataKey="Income"  stroke="#10b981" strokeWidth={2} fill="url(#incG)" dot={false} />
                  <Area type="monotone" dataKey="Expense" stroke="#f87171" strokeWidth={2} fill="url(#expG)" dot={false} />
                  <Area type="monotone" dataKey="Cash Flow" stroke="#60a5fa" strokeWidth={2} strokeDasharray="5 3" fill="none" dot={false} />
                </AreaChart>
              </ResponsiveContainer>
            )}
          </CardContent>
        </Card>

        {/* Stacked bar — expense by category */}
        <Card className="bg-slate-800/50 border-slate-700/50">
          <CardHeader className="pb-1">
            <CardTitle className="text-white text-sm">Expense by Category</CardTitle>
          </CardHeader>
          <CardContent>
            {isLoading ? (
              <div className="h-48 bg-slate-700/20 rounded-lg animate-pulse" />
            ) : stackedData.length === 0 ? (
              <div className="h-48 flex items-center justify-center text-slate-600 text-sm">No data</div>
            ) : (
              <ResponsiveContainer width="100%" height={200}>
                <BarChart data={stackedData} margin={{ top: 4, right: 4, left: 0, bottom: 0 }}>
                  <CartesianGrid strokeDasharray="3 3" stroke="#334155" vertical={false} />
                  <XAxis dataKey="month" tick={{ fill: "#94a3b8", fontSize: 10 }} axisLine={false} tickLine={false} />
                  <YAxis tickFormatter={(v) => `$${(v/1000).toFixed(0)}k`} tick={{ fill: "#94a3b8", fontSize: 10 }} axisLine={false} tickLine={false} width={40} />
                  <Tooltip
                    contentStyle={{ backgroundColor: "#1e293b", border: "1px solid #334155", borderRadius: "8px", fontSize: 11 }}
                    labelStyle={{ color: "#94a3b8" }}
                    formatter={(v) => formatCents(Number(v ?? 0) * 100)}
                  />
                  <Legend iconType="circle" iconSize={7} wrapperStyle={{ fontSize: 10, color: "#94a3b8", paddingTop: 6 }} />
                  {topExpCats.map((cat, i) => (
                    <Bar key={cat.key} dataKey={cat.name} stackId="a" fill={CAT_COLORS[i % CAT_COLORS.length]} radius={i === topExpCats.length - 1 ? [3, 3, 0, 0] : [0, 0, 0, 0]} />
                  ))}
                </BarChart>
              </ResponsiveContainer>
            )}
          </CardContent>
        </Card>
      </div>

      {/* Category breakdown — income & expenses side by side */}
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
        {/* Income categories */}
        <Card className="bg-slate-800/50 border-slate-700/50">
          <CardHeader className="pb-2">
            <CardTitle className="text-white text-sm flex items-center gap-2">
              <TrendingUp className="h-4 w-4 text-emerald-400" />
              Projected Income — by source
            </CardTitle>
          </CardHeader>
          <CardContent>
            {isLoading ? (
              Array.from({ length: 3 }).map((_, i) => (
                <div key={i} className="h-10 bg-slate-700/30 rounded mb-2 animate-pulse" />
              ))
            ) : incomeCats.length === 0 ? (
              <div className="py-8 text-center text-slate-600 text-sm">
                Add recurring income transactions to see projections
              </div>
            ) : (
              incomeCats.map((cat) => (
                <CategoryRow key={cat.key + cat.type} cat={cat} maxCents={maxIncomeCents} />
              ))
            )}
          </CardContent>
        </Card>

        {/* Expense categories */}
        <Card className="bg-slate-800/50 border-slate-700/50">
          <CardHeader className="pb-2">
            <CardTitle className="text-white text-sm flex items-center gap-2">
              <TrendingDown className="h-4 w-4 text-red-400" />
              Projected Expenses — by category
            </CardTitle>
          </CardHeader>
          <CardContent>
            {isLoading ? (
              Array.from({ length: 4 }).map((_, i) => (
                <div key={i} className="h-10 bg-slate-700/30 rounded mb-2 animate-pulse" />
              ))
            ) : expenseCats.length === 0 ? (
              <div className="py-8 text-center text-slate-600 text-sm">
                Add loans or recurring expenses to see projections
              </div>
            ) : (
              expenseCats.map((cat) => (
                <CategoryRow key={cat.key + cat.type} cat={cat} maxCents={maxExpenseCents} />
              ))
            )}
          </CardContent>
        </Card>
      </div>

      {/* Source legend */}
      <div className="flex flex-wrap gap-4 text-xs text-slate-500 px-1">
        <div className="flex items-center gap-1.5 text-blue-400">
          <RefreshCw className="h-3 w-3" /> Recurring transactions (exact amount)
        </div>
        <div className="flex items-center gap-1.5 text-amber-400">
          <Landmark className="h-3 w-3" /> Loan EMI (from amortization schedule)
        </div>
        <div className="flex items-center gap-1.5 text-slate-400">
          <BarChart2 className="h-3 w-3" /> 3-month historical average (variable categories)
        </div>
      </div>

      {/* Month-by-month drilldown */}
      <div>
        <h2 className="text-sm font-semibold text-slate-300 mb-3">Month-by-Month Detail</h2>
        <div className="space-y-2">
          {isLoading ? (
            Array.from({ length: 4 }).map((_, i) => (
              <div key={i} className="h-14 bg-slate-800/30 rounded-xl animate-pulse" />
            ))
          ) : (data?.monthly ?? []).length === 0 ? (
            <Card className="bg-slate-800/30 border-slate-700/50 border-dashed">
              <CardContent className="py-12 text-center text-slate-500 text-sm">
                No projection data — add recurring transactions or loans
              </CardContent>
            </Card>
          ) : (
            (data?.monthly ?? []).map((m) => <MonthRow key={m.month} month={m} />)
          )}
        </div>
      </div>
    </div>
  );
}
