import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import {
  getNetWorthReport,
  getIncomeExpenseReport,
  getCategoryBreakdown,
  getBudgetVsActual,
  getSpendingTrends,
  getBalanceSheet,
} from "@/api/reports";
import type { BalanceSheetGroup } from "@/api/reports";
import { formatCurrency } from "@/utils/currency";
import { cn } from "@/utils/cn";
import {
  AreaChart, Area, BarChart, Bar,
  PieChart, Pie, Cell, XAxis, YAxis, CartesianGrid,
  Tooltip, ResponsiveContainer, Legend
} from "recharts";
import { TrendingUp, TrendingDown, Minus, Landmark, CreditCard } from "lucide-react";

const TABS = ["Balance Sheet", "Net Worth", "Income vs Expense", "Categories", "Budget vs Actual", "Spending Trends"] as const;
type Tab = typeof TABS[number];

const COLORS = [
  "#6366f1", "#22c55e", "#f97316", "#ec4899", "#14b8a6",
  "#f59e0b", "#8b5cf6", "#06b6d4", "#84cc16", "#ef4444",
];

const ASSET_COLORS = ["#22c55e", "#14b8a6", "#6366f1", "#8b5cf6", "#06b6d4", "#84cc16"];
const LIABILITY_COLORS = ["#ef4444", "#f97316", "#ec4899"];

function StatCard({ label, value, change, currency }: {
  label: string; value: number; change?: number; currency: string;
}) {
  const positive = change !== undefined ? change >= 0 : undefined;
  return (
    <div className="bg-card border border-border rounded-xl p-4">
      <p className="text-xs text-muted-foreground mb-1">{label}</p>
      <p className="text-xl font-bold tabular-nums">{formatCurrency(value, currency)}</p>
      {change !== undefined && (
        <div className={cn("flex items-center gap-1 mt-1 text-xs", positive ? "text-success" : "text-destructive")}>
          {positive ? <TrendingUp className="w-3 h-3" /> : <TrendingDown className="w-3 h-3" />}
          {positive ? "+" : ""}{formatCurrency(change, currency)} (30d)
        </div>
      )}
    </div>
  );
}

function GroupRow({ account, color }: { account: { name: string; type: string; balance: number; currency: string }; color: string }) {
  return (
    <div className="flex items-center gap-3 py-2 border-b border-border/40 last:border-0">
      <div className="w-1.5 h-6 rounded-full shrink-0" style={{ background: color }} />
      <div className="flex-1 min-w-0">
        <p className="text-sm truncate">{account.name}</p>
        <p className="text-xs text-muted-foreground capitalize">{account.type.replace(/_/g, " ")}</p>
      </div>
      <p className="text-sm font-semibold tabular-nums shrink-0">
        {formatCurrency(account.balance, account.currency)}
      </p>
    </div>
  );
}

function BalanceSheetTab() {
  const { data, isLoading } = useQuery({ queryKey: ["report-balance-sheet"], queryFn: getBalanceSheet });
  if (isLoading) return <ChartSkeleton />;
  if (!data) return null;

  const noAccounts = data.asset_groups.length === 0 && data.liability_groups.length === 0;
  if (noAccounts) return <EmptyChart message="No accounts found" />;

  // Build stacked bar data: one bar for assets, one for liabilities
  const assetBarData = data.asset_groups.map((g, i) => ({
    name: g.label,
    value: Number(g.subtotal),
    color: ASSET_COLORS[i % ASSET_COLORS.length],
  }));
  const liabilityBarData = data.liability_groups.map((g, i) => ({
    name: g.label,
    value: Number(g.subtotal),
    color: LIABILITY_COLORS[i % LIABILITY_COLORS.length],
  }));

  // Single stacked bar chart showing asset composition vs liability composition
  const maxVal = Math.max(Number(data.total_assets), Number(data.total_liabilities), 1);

  return (
    <div className="space-y-6">
      {/* Summary KPIs */}
      <div className="grid grid-cols-3 gap-4">
        <div className="bg-card border border-border rounded-xl p-4">
          <p className="text-xs text-muted-foreground mb-1">Total Assets</p>
          <p className="text-xl font-bold tabular-nums text-success">{formatCurrency(Number(data.total_assets), data.currency)}</p>
        </div>
        <div className="bg-card border border-border rounded-xl p-4">
          <p className="text-xs text-muted-foreground mb-1">Total Liabilities</p>
          <p className="text-xl font-bold tabular-nums text-destructive">{formatCurrency(Number(data.total_liabilities), data.currency)}</p>
        </div>
        <div className="bg-card border border-border rounded-xl p-4">
          <p className="text-xs text-muted-foreground mb-1">Net Worth</p>
          <p className={cn("text-xl font-bold tabular-nums", Number(data.net_worth) >= 0 ? "text-primary" : "text-destructive")}>
            {formatCurrency(Number(data.net_worth), data.currency)}
          </p>
        </div>
      </div>

      {/* Visual proportion bars */}
      <div className="bg-card border border-border rounded-xl p-5 space-y-4">
        <p className="text-sm font-medium">Asset & Liability Composition</p>

        {/* Assets bar */}
        {assetBarData.length > 0 && (
          <div className="space-y-1.5">
            <div className="flex justify-between text-xs text-muted-foreground">
              <span className="font-medium text-foreground flex items-center gap-1.5">
                <Landmark className="w-3.5 h-3.5" /> Assets
              </span>
              <span>{formatCurrency(Number(data.total_assets), data.currency)}</span>
            </div>
            <div className="flex h-7 rounded-lg overflow-hidden gap-px bg-secondary">
              {assetBarData.map((seg) => (
                <div
                  key={seg.name}
                  className="transition-all duration-500"
                  style={{
                    width: `${(seg.value / maxVal) * 100}%`,
                    background: seg.color,
                    minWidth: seg.value > 0 ? "2px" : "0",
                  }}
                  title={`${seg.name}: ${formatCurrency(seg.value, data.currency)}`}
                />
              ))}
            </div>
            <div className="flex flex-wrap gap-x-4 gap-y-1">
              {assetBarData.map((seg) => (
                <div key={seg.name} className="flex items-center gap-1.5 text-xs text-muted-foreground">
                  <div className="w-2 h-2 rounded-full" style={{ background: seg.color }} />
                  {seg.name}
                </div>
              ))}
            </div>
          </div>
        )}

        {/* Liabilities bar */}
        {liabilityBarData.length > 0 && (
          <div className="space-y-1.5">
            <div className="flex justify-between text-xs text-muted-foreground">
              <span className="font-medium text-foreground flex items-center gap-1.5">
                <CreditCard className="w-3.5 h-3.5" /> Liabilities
              </span>
              <span>{formatCurrency(Number(data.total_liabilities), data.currency)}</span>
            </div>
            <div className="flex h-7 rounded-lg overflow-hidden gap-px bg-secondary">
              {liabilityBarData.map((seg) => (
                <div
                  key={seg.name}
                  className="transition-all duration-500"
                  style={{
                    width: `${(seg.value / maxVal) * 100}%`,
                    background: seg.color,
                    minWidth: seg.value > 0 ? "2px" : "0",
                  }}
                  title={`${seg.name}: ${formatCurrency(seg.value, data.currency)}`}
                />
              ))}
            </div>
            <div className="flex flex-wrap gap-x-4 gap-y-1">
              {liabilityBarData.map((seg) => (
                <div key={seg.name} className="flex items-center gap-1.5 text-xs text-muted-foreground">
                  <div className="w-2 h-2 rounded-full" style={{ background: seg.color }} />
                  {seg.name}
                </div>
              ))}
            </div>
          </div>
        )}
      </div>

      {/* Side-by-side account breakdown */}
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
        {/* Assets */}
        <div className="bg-card border border-border rounded-xl p-5">
          <div className="flex items-center justify-between mb-4">
            <h3 className="text-sm font-semibold flex items-center gap-2">
              <Landmark className="w-4 h-4 text-success" /> Assets
            </h3>
            <span className="text-sm font-bold text-success tabular-nums">
              {formatCurrency(Number(data.total_assets), data.currency)}
            </span>
          </div>
          <div className="space-y-4">
            {data.asset_groups.map((group: BalanceSheetGroup, gi: number) => (
              <div key={group.label}>
                <div className="flex justify-between items-center mb-1">
                  <p className="text-xs font-medium text-muted-foreground uppercase tracking-wider">{group.label}</p>
                  <p className="text-xs font-semibold tabular-nums">{formatCurrency(Number(group.subtotal), data.currency)}</p>
                </div>
                {group.accounts.map((acc) => (
                  <GroupRow key={acc.id} account={acc} color={ASSET_COLORS[gi % ASSET_COLORS.length]} />
                ))}
              </div>
            ))}
          </div>
        </div>

        {/* Liabilities */}
        <div className="bg-card border border-border rounded-xl p-5">
          <div className="flex items-center justify-between mb-4">
            <h3 className="text-sm font-semibold flex items-center gap-2">
              <CreditCard className="w-4 h-4 text-destructive" /> Liabilities
            </h3>
            <span className="text-sm font-bold text-destructive tabular-nums">
              {formatCurrency(Number(data.total_liabilities), data.currency)}
            </span>
          </div>
          {data.liability_groups.length === 0 ? (
            <p className="text-sm text-muted-foreground py-4 text-center">No liabilities — great work!</p>
          ) : (
            <div className="space-y-4">
              {data.liability_groups.map((group: BalanceSheetGroup, gi: number) => (
                <div key={group.label}>
                  <div className="flex justify-between items-center mb-1">
                    <p className="text-xs font-medium text-muted-foreground uppercase tracking-wider">{group.label}</p>
                    <p className="text-xs font-semibold tabular-nums">{formatCurrency(Number(group.subtotal), data.currency)}</p>
                  </div>
                  {group.accounts.map((acc) => (
                    <GroupRow key={acc.id} account={acc} color={LIABILITY_COLORS[gi % LIABILITY_COLORS.length]} />
                  ))}
                </div>
              ))}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

function NetWorthTab() {
  const { data, isLoading } = useQuery({ queryKey: ["report-net-worth"], queryFn: () => getNetWorthReport(12) });
  if (isLoading) return <ChartSkeleton />;
  if (!data) return null;

  return (
    <div className="space-y-4">
      <div className="grid grid-cols-3 gap-4">
        <StatCard label="Net Worth" value={Number(data.current_net_worth)} change={Number(data.change_30d)} currency={data.base_currency} />
        <div className="bg-card border border-border rounded-xl p-4">
          <p className="text-xs text-muted-foreground mb-1">30d Change</p>
          <p className={cn("text-xl font-bold tabular-nums", Number(data.change_30d_pct) >= 0 ? "text-success" : "text-destructive")}>
            {Number(data.change_30d_pct) >= 0 ? "+" : ""}{Number(data.change_30d_pct).toFixed(2)}%
          </p>
        </div>
        <div className="bg-card border border-border rounded-xl p-4">
          <p className="text-xs text-muted-foreground mb-1">History</p>
          <p className="text-xl font-bold tabular-nums">{data.points.length} snapshot{data.points.length !== 1 ? "s" : ""}</p>
        </div>
      </div>
      {data.points.length === 0 ? (
        <EmptyChart message="No snapshots yet — snapshots are taken daily at 2am" />
      ) : (
        <div className="bg-card border border-border rounded-xl p-4">
          <p className="text-sm font-medium mb-4">Net Worth Over Time</p>
          <ResponsiveContainer width="100%" height={300}>
            <AreaChart data={data.points.map(p => ({ ...p, net_worth: Number(p.net_worth), total_assets: Number(p.total_assets), total_liabilities: Number(p.total_liabilities) }))}>
              <defs>
                <linearGradient id="nwGrad" x1="0" y1="0" x2="0" y2="1">
                  <stop offset="5%" stopColor="#6366f1" stopOpacity={0.3} />
                  <stop offset="95%" stopColor="#6366f1" stopOpacity={0} />
                </linearGradient>
              </defs>
              <CartesianGrid strokeDasharray="3 3" stroke="var(--border)" />
              <XAxis dataKey="date" tick={{ fontSize: 11 }} stroke="var(--muted-foreground)" />
              <YAxis tick={{ fontSize: 11 }} stroke="var(--muted-foreground)" tickFormatter={(v) => `£${(v/1000).toFixed(0)}k`} />
              <Tooltip formatter={(v: number) => formatCurrency(v, data.base_currency)} />
              <Area type="monotone" dataKey="net_worth" stroke="#6366f1" fill="url(#nwGrad)" strokeWidth={2} name="Net Worth" />
              <Area type="monotone" dataKey="total_assets" stroke="#22c55e" fill="none" strokeWidth={1.5} strokeDasharray="4 2" name="Assets" />
              <Area type="monotone" dataKey="total_liabilities" stroke="#ef4444" fill="none" strokeWidth={1.5} strokeDasharray="4 2" name="Liabilities" />
            </AreaChart>
          </ResponsiveContainer>
        </div>
      )}
    </div>
  );
}

function IncomeExpenseTab() {
  const { data, isLoading } = useQuery({ queryKey: ["report-income-expense"], queryFn: () => getIncomeExpenseReport(12) });
  if (isLoading) return <ChartSkeleton />;
  if (!data) return null;

  const chartData = data.points.map(p => ({ ...p, income: Number(p.income), expenses: Number(p.expenses), net: Number(p.net) }));
  return (
    <div className="space-y-4">
      <div className="grid grid-cols-4 gap-4">
        <StatCard label="Total Income" value={Number(data.total_income)} currency={data.currency} />
        <StatCard label="Total Expenses" value={Number(data.total_expenses)} currency={data.currency} />
        <StatCard label="Avg Monthly Income" value={Number(data.avg_monthly_income)} currency={data.currency} />
        <StatCard label="Avg Monthly Expenses" value={Number(data.avg_monthly_expenses)} currency={data.currency} />
      </div>
      {chartData.length === 0 ? <EmptyChart /> : (
        <div className="bg-card border border-border rounded-xl p-4">
          <p className="text-sm font-medium mb-4">Monthly Income vs Expenses</p>
          <ResponsiveContainer width="100%" height={300}>
            <BarChart data={chartData}>
              <CartesianGrid strokeDasharray="3 3" stroke="var(--border)" />
              <XAxis dataKey="month" tick={{ fontSize: 11 }} stroke="var(--muted-foreground)" />
              <YAxis tick={{ fontSize: 11 }} stroke="var(--muted-foreground)" tickFormatter={(v) => `£${(v/1000).toFixed(0)}k`} />
              <Tooltip formatter={(v: number) => formatCurrency(v, data.currency)} />
              <Legend />
              <Bar dataKey="income" fill="#22c55e" name="Income" radius={[2, 2, 0, 0]} />
              <Bar dataKey="expenses" fill="#ef4444" name="Expenses" radius={[2, 2, 0, 0]} />
            </BarChart>
          </ResponsiveContainer>
        </div>
      )}
    </div>
  );
}

function CategoriesTab() {
  const { data, isLoading } = useQuery({ queryKey: ["report-categories"], queryFn: () => getCategoryBreakdown() });
  if (isLoading) return <ChartSkeleton />;
  if (!data) return null;

  const pieData = data.items.slice(0, 10).map(i => ({ name: i.category_name, value: Number(i.amount) }));
  return (
    <div className="space-y-4">
      <div className="bg-card border border-border rounded-xl p-4">
        <p className="text-sm font-medium mb-1">Expense Breakdown — This Month</p>
        <p className="text-xs text-muted-foreground mb-4">Total: {formatCurrency(Number(data.total), data.currency)}</p>
        {pieData.length === 0 ? <EmptyChart /> : (
          <div className="flex gap-6 items-start">
            <ResponsiveContainer width={220} height={220}>
              <PieChart>
                <Pie data={pieData} cx="50%" cy="50%" innerRadius={60} outerRadius={90} dataKey="value" paddingAngle={2}>
                  {pieData.map((_, i) => <Cell key={i} fill={COLORS[i % COLORS.length]} />)}
                </Pie>
                <Tooltip formatter={(v: number) => formatCurrency(v, data.currency)} />
              </PieChart>
            </ResponsiveContainer>
            <div className="flex-1 space-y-2">
              {data.items.slice(0, 10).map((item, i) => (
                <div key={i} className="flex items-center gap-2 text-sm">
                  <div className="w-2.5 h-2.5 rounded-full shrink-0" style={{ background: COLORS[i % COLORS.length] }} />
                  <span className="flex-1 truncate text-muted-foreground">{item.category_name}</span>
                  <span className="font-medium tabular-nums">{formatCurrency(Number(item.amount), data.currency)}</span>
                  <span className="text-xs text-muted-foreground w-10 text-right">{item.percent}%</span>
                </div>
              ))}
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

function BudgetVsActualTab() {
  const { data, isLoading } = useQuery({ queryKey: ["report-budget-actual"], queryFn: getBudgetVsActual });
  if (isLoading) return <ChartSkeleton />;
  if (!data || data.items.length === 0) return <EmptyChart message="No active budgets" />;

  const chartData = data.items.map(i => ({
    name: i.budget_name,
    budgeted: Number(i.budgeted),
    actual: Number(i.actual),
  }));

  return (
    <div className="space-y-4">
      <div className="grid grid-cols-2 gap-4">
        <StatCard label="Total Budgeted" value={Number(data.total_budgeted)} currency={data.currency} />
        <StatCard label="Total Actual" value={Number(data.total_actual)} currency={data.currency} />
      </div>
      <div className="bg-card border border-border rounded-xl p-4">
        <p className="text-sm font-medium mb-4">Budget vs Actual Spending</p>
        <ResponsiveContainer width="100%" height={300}>
          <BarChart data={chartData} layout="vertical">
            <CartesianGrid strokeDasharray="3 3" stroke="var(--border)" />
            <XAxis type="number" tick={{ fontSize: 11 }} stroke="var(--muted-foreground)" tickFormatter={(v) => `£${v}`} />
            <YAxis type="category" dataKey="name" tick={{ fontSize: 11 }} stroke="var(--muted-foreground)" width={120} />
            <Tooltip formatter={(v: number) => formatCurrency(v, data.currency)} />
            <Legend />
            <Bar dataKey="budgeted" fill="#6366f1" name="Budgeted" radius={[0, 2, 2, 0]} />
            <Bar dataKey="actual" fill="#f97316" name="Actual" radius={[0, 2, 2, 0]} />
          </BarChart>
        </ResponsiveContainer>
      </div>
    </div>
  );
}

function SpendingTrendsTab() {
  const { data, isLoading } = useQuery({ queryKey: ["report-spending-trends"], queryFn: () => getSpendingTrends(6) });
  if (isLoading) return <ChartSkeleton />;
  if (!data || data.points.length === 0) return <EmptyChart />;

  const months = [...new Set(data.points.map(p => p.month))].sort();
  const chartData = months.map(month => {
    const row: Record<string, string | number> = { month };
    data.categories.forEach(cat => {
      const pt = data.points.find(p => p.month === month && p.category_name === cat);
      row[cat] = pt ? Number(pt.amount) : 0;
    });
    return row;
  });

  return (
    <div className="bg-card border border-border rounded-xl p-4">
      <p className="text-sm font-medium mb-4">Spending by Category (6 months)</p>
      <ResponsiveContainer width="100%" height={320}>
        <BarChart data={chartData}>
          <CartesianGrid strokeDasharray="3 3" stroke="var(--border)" />
          <XAxis dataKey="month" tick={{ fontSize: 11 }} stroke="var(--muted-foreground)" />
          <YAxis tick={{ fontSize: 11 }} stroke="var(--muted-foreground)" tickFormatter={(v) => `£${v}`} />
          <Tooltip formatter={(v: number) => formatCurrency(v, data.currency)} />
          <Legend />
          {data.categories.slice(0, 8).map((cat, i) => (
            <Bar key={cat} dataKey={cat} stackId="a" fill={COLORS[i % COLORS.length]} />
          ))}
        </BarChart>
      </ResponsiveContainer>
    </div>
  );
}

function ChartSkeleton() {
  return (
    <div className="space-y-4">
      <div className="grid grid-cols-3 gap-4">
        {[1, 2, 3].map(i => <div key={i} className="h-20 bg-card border border-border rounded-xl animate-pulse" />)}
      </div>
      <div className="h-80 bg-card border border-border rounded-xl animate-pulse" />
    </div>
  );
}

function EmptyChart({ message = "No data for this period" }: { message?: string }) {
  return (
    <div className="bg-card border border-border rounded-xl py-16 text-center text-muted-foreground">
      <Minus className="w-8 h-8 mx-auto mb-2 opacity-30" />
      <p>{message}</p>
    </div>
  );
}

export default function ReportsPage() {
  const [activeTab, setActiveTab] = useState<Tab>("Balance Sheet");

  return (
    <div className="space-y-6">
      <div>
        <h1 className="text-2xl font-bold">Reports</h1>
        <p className="text-sm text-muted-foreground mt-1">Financial insights and analysis</p>
      </div>

      <div className="flex gap-1 border-b border-border overflow-x-auto scrollbar-none">
        {TABS.map((tab) => (
          <button
            key={tab}
            onClick={() => setActiveTab(tab)}
            className={cn(
              "px-4 py-2.5 text-sm font-medium border-b-2 transition-colors whitespace-nowrap",
              activeTab === tab
                ? "border-primary text-foreground"
                : "border-transparent text-muted-foreground hover:text-foreground"
            )}
          >
            {tab}
          </button>
        ))}
      </div>

      <div>
        {activeTab === "Balance Sheet" && <BalanceSheetTab />}
        {activeTab === "Net Worth" && <NetWorthTab />}
        {activeTab === "Income vs Expense" && <IncomeExpenseTab />}
        {activeTab === "Categories" && <CategoriesTab />}
        {activeTab === "Budget vs Actual" && <BudgetVsActualTab />}
        {activeTab === "Spending Trends" && <SpendingTrendsTab />}
      </div>
    </div>
  );
}
