"use client";

import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import {
  BarChart,
  Bar,
  XAxis,
  YAxis,
  Tooltip,
  ResponsiveContainer,
  LineChart,
  Line,
  CartesianGrid,
  Legend,
} from "recharts";
import {
  getStatements,
  type KpiSummary,
  type PnLRow,
  type CfsRow,
  type BsRow,
  type DebtYearRow,
  type GenerationRow,
  type IdcPhasing,
} from "@/lib/api";
import { KpiCard } from "@/components/KpiCard";

// Horizontal table
// ---------------------------------------------------------------------------

interface TableRow {
  label: string;
  values: (number | null)[];
  isBold?: boolean;
  isSeparator?: boolean;
  isHeader?: boolean;
  format?: (v: number | null) => string;
  indent?: boolean;
  collapsible?: boolean;
  isHighlight?: boolean;
  children?: TableRow[];
}

function n1(v: number | null) {
  return v == null ? "—" : v.toFixed(1);
}
function n2(v: number | null) {
  return v == null ? "—" : v.toFixed(2);
}
function pct1(v: number | null) {
  return v == null ? "—" : `${(v * 100).toFixed(1)}%`;
}

function HorizontalTable({
  years,
  rows,
  unit = "INR Cr",
  yearPrefix = "Y",
}: {
  years: number[];
  rows: TableRow[];
  unit?: string;
  yearPrefix?: string;
}) {
  const [expandedRows, setExpandedRows] = useState<Set<number>>(new Set());

  const toggleRow = (idx: number) => {
    setExpandedRows((prev) => {
      const next = new Set(prev);
      if (next.has(idx)) {
        next.delete(idx);
      } else {
        next.add(idx);
      }
      return next;
    });
  };

  let rowIndex = 0;

  return (
    <div className="overflow-x-auto rounded-lg border border-border">
      <table className="text-xs border-collapse whitespace-nowrap">
        <thead>
          <tr className="bg-muted/70">
            <th className="sticky left-0 z-20 bg-muted/70 px-3 py-2 text-left font-semibold border-r border-b min-w-[220px] text-muted-foreground">
              Metric ({unit})
            </th>
            {years.map((y) => (
              <th
                key={y}
                className="px-3 py-2 text-right font-semibold border-b min-w-[68px] text-muted-foreground"
              >
                {yearPrefix}{y}
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {rows.map((row, i) => {
            rowIndex = i;
            const isExpanded = expandedRows.has(i);

            if (row.isSeparator) {
              return (
                <tr key={i}>
                  <td colSpan={years.length + 1} className="bg-border/40 h-px p-0" />
                </tr>
              );
            }

            if (row.isHeader) {
              return (
                <tr key={i} className="bg-primary/5">
                  <td
                    colSpan={years.length + 1}
                    className="sticky left-0 z-10 px-3 py-1 text-[10px] font-semibold uppercase tracking-wider text-primary/70 bg-primary/5"
                  >
                    {row.label}
                  </td>
                </tr>
              );
            }

            return (
              <>
                <tr
                  key={i}
                  className={`border-t border-border/50 transition-colors hover:bg-accent/40 ${
                    row.isBold ? "font-semibold bg-muted/20" : ""
                  }`}
                >
                  <td
                    className={`sticky left-0 z-10 border-r border-border/50 px-3 py-1.5 ${
                      row.isHighlight ? "bg-blue-50" : "bg-background"
                    } ${
                      row.indent ? "pl-6 text-muted-foreground" : ""
                    } ${row.collapsible ? "cursor-pointer hover:text-primary" : ""}`}
                    onClick={() => row.collapsible && toggleRow(i)}
                  >
                    {row.collapsible && (
                      <span className="mr-0.5 text-[6px]">{isExpanded ? "▼" : "▶"}</span>
                    )}
                    {row.label}
                  </td>
                  {row.values.map((v, j) => (
                    <td key={j} className={`px-3 py-1.5 text-right tabular-nums ${row.isHighlight ? "bg-blue-50" : ""}`}>
                      {row.format ? row.format(v) : n1(v)}
                    </td>
                  ))}
                </tr>
                {row.collapsible && row.children && isExpanded && row.children.map((child, ci) => (
                  <tr key={`${i}-${ci}`} className="border-t border-border/30 bg-muted/30">
                    <td className="sticky left-0 z-10 bg-muted/30 border-r border-border/30 px-3 pl-8 py-1.5 text-muted-foreground">
                      {child.label}
                    </td>
                    {child.values.map((v, j) => (
                      <td key={j} className="px-3 py-1.5 text-right tabular-nums text-muted-foreground">
                        {child.format ? child.format(v) : n1(v)}
                      </td>
                    ))}
                  </tr>
                ))}
              </>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Sheet content builders
// ---------------------------------------------------------------------------

function buildPnLRows(pnl: PnLRow[]): TableRow[] {
  const ppaChildren: TableRow[] = [
    { label: "Units (MWh)", values: pnl.map((r) => r.ppa_units_mwh), format: (v) => v == null ? "—" : Math.round(v).toLocaleString() },
    { label: "Tariff (₹/kWh)", values: pnl.map((r) => r.ppa_tariff_inr_per_kwh) },
  ];
  const mcpChildren: TableRow[] = [
    { label: "MCP Units (MWh)", values: pnl.map((r) => r.mcp_units_mwh), format: (v) => v == null ? "—" : Math.round(v).toLocaleString() },
  ];
  const opexChildren: TableRow[] = [
    { label: "O&M Opex", values: pnl.map((r) => r.om_cr) },
    { label: "Insurance", values: pnl.map((r) => r.insurance_cr) },
    { label: "Land Lease", values: pnl.map((r) => r.land_lease_cr) },
    { label: "AM Fee", values: pnl.map((r) => r.am_fee_cr) },
    { label: "Misc Opex", values: pnl.map((r) => r.misc_opex_cr) },
  ];
  return [
    {
      label: "PPA Revenue",
      values: pnl.map((r) => r.ppa_revenue_cr),
      isBold: true,
      collapsible: true,
      children: ppaChildren
    },
    { isSeparator: true, label: "", values: [] },
    {
      label: "MCP Revenue",
      values: pnl.map((r) => r.mcp_revenue_cr),
      collapsible: true,
      children: mcpChildren
    },
    { isSeparator: true, label: "", values: [] },
    { label: "Total Revenue", values: pnl.map((r) => r.revenue_cr), isBold: true, isHighlight: true },
    { isSeparator: true, label: "", values: [] },
    {
      label: "Operating Expenditure",
      values: pnl.map((r) => r.opex_total_cr),
      collapsible: true,
      children: opexChildren
    },
    { isSeparator: true, label: "", values: [] },
    { label: "EBITDA", values: pnl.map((r) => r.ebitda_cr), isBold: true, isHighlight: true },
    { label: "Book Depreciation", values: pnl.map((r) => r.depreciation_book_cr), indent: true },
    { label: "EBIT", values: pnl.map((r) => r.ebit_cr), isBold: true, isHighlight: true, format: n2 },
    { label: "Interest", values: pnl.map((r) => r.interest_cr), indent: true },
    { label: "PBT", values: pnl.map((r) => r.pbt_cr), isBold: true, isHighlight: true, format: n2 },
    { label: "Tax", values: pnl.map((r) => r.tax_cr), indent: true },
    { label: "PAT", values: pnl.map((r) => r.pat_cr), isBold: true, isHighlight: true, format: n2 },
  ];
}

function buildCfsRows(cfs: CfsRow[], kpis: KpiSummary, pnl: PnLRow[]): TableRow[] {
  // CFADS = CFO + Interest (add back since CFO is post-interest in this model)
  const cfads = cfs.map((r, i) => r.cfo_cr + (pnl[i]?.interest_cr ?? 0));
  const equityCf = cfs.map((r, i) => cfads[i] - r.debt_repayment_cr - (pnl[i]?.interest_cr ?? 0));

  return [
    { isHeader: true, label: "Operating Cash Flow", values: [] },
    { label: "PAT", values: cfs.map((r) => r.pat_cr), indent: true },
    { label: "Add: Depreciation", values: cfs.map((r) => r.depreciation_cr), indent: true },
    { label: "Δ Working Capital", values: cfs.map((r) => r.delta_working_capital_cr), indent: true },
    { label: "CFO", values: cfs.map((r) => r.cfo_cr), isBold: true },
    { isSeparator: true, label: "", values: [] },
    { isHeader: true, label: "Investing Cash Flow", values: [] },
    { label: "Capex", values: cfs.map((r) => r.capex_cr), indent: true },
    { label: "CFI", values: cfs.map((r) => r.cfi_cr), isBold: true },
    { isSeparator: true, label: "", values: [] },
    { isHeader: true, label: "Financing Cash Flow", values: [] },
    { label: "Debt Drawdown", values: cfs.map((r) => r.debt_drawdown_cr), indent: true },
    { label: "Debt Repayment", values: cfs.map((r) => r.debt_repayment_cr), indent: true },
    { label: "Equity Injection", values: cfs.map((r) => r.equity_injection_cr), indent: true },
    { label: "CFF", values: cfs.map((r) => r.cff_cr), isBold: true },
    { isSeparator: true, label: "", values: [] },
    { label: "Net Cash Flow", values: cfs.map((r) => r.net_cash_flow_cr), isBold: true },
    { label: "Opening Cash", values: cfs.map((r) => r.opening_cash_cr), indent: true },
    { label: "Closing Cash", values: cfs.map((r) => r.closing_cash_cr), isBold: true },
    { isSeparator: true, label: "", values: [] },
    { isHeader: true, label: "Returns Analysis", values: [] },
    { label: "CFADS (pre-debt service)", values: cfads, isBold: true },
    { label: "Equity Free Cash Flow", values: equityCf },
    {
      label: `Project IRR: ${kpis.project_irr != null ? (kpis.project_irr * 100).toFixed(1) + "%" : "—"}  |  Equity IRR: ${kpis.equity_irr != null ? (kpis.equity_irr * 100).toFixed(1) + "%" : "—"}`,
      values: [],
      isBold: true,
    },
  ];
}

function buildBsRows(bs: BsRow[]): TableRow[] {
  return [
    { isHeader: true, label: "Assets", values: [] },
    { label: "Gross Block", values: bs.map((r) => r.gross_block_cr), indent: true },
    { label: "Less: Accum Depr", values: bs.map((r) => r.accumulated_depr_cr), indent: true },
    { label: "Net Block", values: bs.map((r) => r.net_block_cr), isBold: true },
    { isSeparator: true, label: "", values: [] },
    { label: "Cash & Bank", values: bs.map((r) => r.cash_cr), indent: true },
    { label: "Receivables", values: bs.map((r) => r.receivables_cr), indent: true },
    { label: "Total Assets", values: bs.map((r) => r.total_assets_cr), isBold: true },
    { isSeparator: true, label: "", values: [] },
    { isHeader: true, label: "Liabilities & Equity", values: [] },
    { label: "Equity Share Capital", values: bs.map((r) => r.equity_cr), indent: true },
    { label: "Reserves & Surplus", values: bs.map((r) => r.reserves_cr), indent: true },
    { label: "Long-term Debt", values: bs.map((r) => r.long_term_debt_cr), indent: true },
    { label: "Payables", values: bs.map((r) => r.payables_cr), indent: true },
    { label: "Total Liabilities", values: bs.map((r) => r.total_liabilities_cr), isBold: true },
  ];
}

function buildDebtRows(debt: DebtYearRow[]): TableRow[] {
  return [
    { label: "Opening Balance", values: debt.map((r) => r.opening_balance_cr) },
    { label: "Interest", values: debt.map((r) => r.interest_cr) },
    { label: "Principal Repayment", values: debt.map((r) => r.principal_cr) },
    { label: "Total Debt Service", values: debt.map((r) => r.total_debt_service_cr), isBold: true },
    { label: "Closing Balance", values: debt.map((r) => r.closing_balance_cr), isBold: true },
    { isSeparator: true, label: "", values: [] },
    { label: "DSCR", values: debt.map((r) => r.dscr), isBold: true, format: n2 },
  ];
}

// ---------------------------------------------------------------------------
// Sheet views
// ---------------------------------------------------------------------------

function SummarySheet({ kpis, scenarioId }: { kpis: KpiSummary; scenarioId: string }) {
  const { data: stmts } = useQuery({
    queryKey: ["statements", scenarioId],
    queryFn: () => getStatements(scenarioId),
  });

  // Custom KPIs - stored in state, persist to localStorage
  const [customKpis, setCustomKpis] = useState<{ label: string; value: string; unit: string }[]>(() => {
    try {
      const stored = localStorage.getItem(`customKpis-${scenarioId}`);
      if (!stored) return [];
      const parsed = JSON.parse(stored);
      if (!Array.isArray(parsed)) return [];
      // Filter out invalid entries
      return parsed.filter(
        (k) => k && typeof k.label === "string" && typeof k.value === "string" && k.value !== "0.0" && k.value !== "null"
      );
    } catch {
      return [];
    }
  });

  function addCustomKpi() {
    const label = prompt("Enter KPI label (e.g. O&M Cost)");
    if (!label) return;
    const value = prompt(`Enter value for ${label} (without unit)`);
    if (!value) return;
    const unit = prompt("Enter unit (e.g. Cr, %, yrs)") || "";
    const newKpis = [...customKpis, { label, value, unit }];
    setCustomKpis(newKpis);
    try {
      localStorage.setItem(`customKpis-${scenarioId}`, JSON.stringify(newKpis));
    } catch {
      // localStorage unavailable
    }
  }

  function removeCustomKpi(index: number) {
    const newKpis = customKpis.filter((_, i) => i !== index);
    setCustomKpis(newKpis);
    try {
      localStorage.setItem(`customKpis-${scenarioId}`, JSON.stringify(newKpis));
    } catch {
      // localStorage unavailable
    }
  }

  const pnlChart =
    stmts?.pnl.map((r) => ({
      year: r.year,
      Revenue: r.revenue_cr,
      EBITDA: r.ebitda_cr,
      PAT: r.pat_cr,
    })) ?? [];

  const cashChart =
    stmts?.cfs.map((r) => ({ year: r.year, "Closing Cash": r.closing_cash_cr })) ?? [];

  return (
    <div className="space-y-6">
      <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3">
        <KpiCard
          label="Solved Tariff"
          value={kpis.solved_tariff_inr_per_kwh != null ? kpis.solved_tariff_inr_per_kwh.toFixed(2) : null}
          unit="₹/kWh"
          highlight
        />
        <KpiCard
          label="Equity IRR"
          value={kpis.equity_irr != null ? `${(kpis.equity_irr * 100).toFixed(1)}%` : null}
          highlight
        />
        <KpiCard label="Project IRR" value={kpis.project_irr != null ? `${(kpis.project_irr * 100).toFixed(1)}%` : null} />
        <KpiCard label="Min DSCR" value={kpis.min_dscr?.toFixed(2) ?? null} />
        <KpiCard label="Avg DSCR" value={kpis.avg_dscr?.toFixed(2) ?? null} />
        <KpiCard label="Total Capex" value={kpis.total_capex_cr != null ? kpis.total_capex_cr.toFixed(1) : null} unit="Cr" />
        <KpiCard label="Debt" value={kpis.debt_cr?.toFixed(1) ?? null} unit="Cr" />
        <KpiCard label="IDC" value={kpis.idc_cr?.toFixed(1) ?? null} unit="Cr" />
        <KpiCard label="LCOE" value={kpis.lcoe_inr_per_kwh?.toFixed(2) ?? null} unit="₹/kWh" />
        <KpiCard label="Payback" value={kpis.payback_years?.toFixed(1) ?? null} unit="yrs" />
        {kpis.solar_y1_cuf != null && (
          <KpiCard label="Solar Y1 CUF" value={`${(kpis.solar_y1_cuf * 100).toFixed(1)}%`} />
        )}
        {kpis.wind_y1_plf != null && (
          <KpiCard label="Wind Y1 PLF" value={`${(kpis.wind_y1_plf * 100).toFixed(1)}%`} />
        )}
        {kpis.rtc_cuf_achieved != null && (
          <KpiCard label="RTC CUF" value={`${(kpis.rtc_cuf_achieved * 100).toFixed(1)}%`} highlight />
        )}

        {/* Add custom KPI button */}
        <button
          onClick={addCustomKpi}
          className="border border-dashed border-primary/30 rounded-lg p-4 flex items-center justify-center text-sm text-primary hover:bg-primary/5 transition-colors"
        >
          + Add KPI
        </button>

        {/* Custom KPIs */}
        {customKpis.map((kpi: { label: string; value: string; unit: string }, i: number) => (
          <div key={i} className="relative">
            <KpiCard label={kpi.label} value={kpi.value} unit={kpi.unit} />
            <button
              onClick={() => removeCustomKpi(i)}
              className="absolute top-1 right-2 text-muted-foreground/40 hover:text-destructive text-xs"
            >
              ×
            </button>
          </div>
        ))}
      </div>

      {stmts && (
        <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
          <div className="border rounded-lg p-4">
            <p className="text-sm font-medium mb-3 text-muted-foreground">P&L Overview (₹Cr)</p>
            <ResponsiveContainer width="100%" height={200}>
              <BarChart data={pnlChart} barCategoryGap="30%">
                <XAxis dataKey="year" tick={{ fontSize: 10 }} />
                <YAxis tick={{ fontSize: 10 }} />
                <Tooltip />
                <Legend iconSize={10} />
                <Bar dataKey="Revenue" fill="oklch(0.52 0.22 262)" />
                <Bar dataKey="EBITDA" fill="oklch(0.60 0.17 178)" />
                <Bar dataKey="PAT" fill="oklch(0.70 0.18 55)" />
              </BarChart>
            </ResponsiveContainer>
          </div>
          <div className="border rounded-lg p-4">
            <p className="text-sm font-medium mb-3 text-muted-foreground">Closing Cash (₹Cr)</p>
            <ResponsiveContainer width="100%" height={200}>
              <LineChart data={cashChart}>
                <CartesianGrid strokeDasharray="3 3" stroke="oklch(0.90 0.01 262)" />
                <XAxis dataKey="year" tick={{ fontSize: 10 }} />
                <YAxis tick={{ fontSize: 10 }} />
                <Tooltip />
                <Line
                  type="monotone"
                  dataKey="Closing Cash"
                  stroke="oklch(0.52 0.22 262)"
                  dot={false}
                  strokeWidth={2}
                />
              </LineChart>
            </ResponsiveContainer>
          </div>
        </div>
      )}
    </div>
  );
}

function IrrSheet({ kpis }: { kpis: KpiSummary }) {
  const sections = [
    {
      title: "Returns",
      rows: [
        { label: "Equity IRR (Leveraged)", value: kpis.equity_irr != null ? pct1(kpis.equity_irr) : "—" },
        { label: "Project IRR (Unlevered)", value: kpis.project_irr != null ? pct1(kpis.project_irr) : "—" },
        { label: "LCOE", value: kpis.lcoe_inr_per_kwh != null ? `₹${kpis.lcoe_inr_per_kwh.toFixed(2)}/kWh` : "—" },
        { label: "Payback Period", value: kpis.payback_years != null ? `${kpis.payback_years.toFixed(1)} yrs` : "—" },
      ],
    },
    {
      title: "Debt Metrics",
      rows: [
        { label: "Min DSCR", value: kpis.min_dscr?.toFixed(2) ?? "—" },
        { label: "Avg DSCR", value: kpis.avg_dscr?.toFixed(2) ?? "—" },
      ],
    },
    {
      title: "Project Economics",
      rows: [
        { label: "Solved / Fixed Tariff", value: kpis.solved_tariff_inr_per_kwh != null ? `₹${kpis.solved_tariff_inr_per_kwh.toFixed(2)}/kWh` : "—" },
        { label: "Total Capex", value: kpis.total_capex_cr != null ? `₹${kpis.total_capex_cr.toFixed(1)} Cr` : "—" },
        { label: "Debt Sized", value: kpis.debt_cr != null ? `₹${kpis.debt_cr.toFixed(1)} Cr` : "—" },
        { label: "IDC", value: kpis.idc_cr != null ? `₹${kpis.idc_cr.toFixed(1)} Cr` : "—" },
      ],
    },
  ];

  return (
    <div className="max-w-xl space-y-4">
      {sections.map((s) => (
        <div key={s.title} className="border rounded-lg overflow-hidden">
          <div className="bg-muted/50 px-4 py-2 text-xs font-semibold uppercase tracking-wider text-muted-foreground">
            {s.title}
          </div>
          <table className="w-full text-sm">
            <tbody>
              {s.rows.map(({ label, value }) => (
                <tr key={label} className="border-t hover:bg-accent/30 transition-colors">
                  <td className="px-4 py-2.5 text-muted-foreground">{label}</td>
                  <td className="px-4 py-2.5 tabular-nums font-semibold text-right">{value}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      ))}
    </div>
  );
}

function buildGenerationRows(gen: GenerationRow[]): TableRow[] {
  const hasSolar = gen.some((r) => r.solar_mwh > 0);
  const hasWind = gen.some((r) => r.wind_mwh > 0);
  const rows: TableRow[] = [];
  if (hasSolar) {
    rows.push({ label: "Solar Generation (MWh)", values: gen.map((r) => r.solar_mwh), format: (v) => v == null ? "—" : Math.round(v).toLocaleString() });
    rows.push({ label: "Solar CUF (%)", values: gen.map((r) => r.solar_cuf_pct), format: (v) => v == null ? "—" : `${v.toFixed(1)}%`, indent: true });
  }
  if (hasWind) {
    rows.push({ label: "Wind Generation (MWh)", values: gen.map((r) => r.wind_mwh), format: (v) => v == null ? "—" : Math.round(v).toLocaleString() });
    rows.push({ label: "Wind PLF (%)", values: gen.map((r) => r.wind_plf_pct), format: (v) => v == null ? "—" : `${v.toFixed(1)}%`, indent: true });
  }
  rows.push({ label: "Gross Total (MWh)", values: gen.map((r) => r.gross_mwh), isBold: true, format: (v) => v == null ? "—" : Math.round(v).toLocaleString() });
  rows.push({ label: "Less: Aux Consumption", values: gen.map((r) => -r.aux_loss_mwh), format: (v) => v == null ? "—" : Math.round(v).toLocaleString(), indent: true });
  rows.push({ label: "Less: Transmission Loss", values: gen.map((r) => -r.tx_loss_mwh), format: (v) => v == null ? "—" : Math.round(v).toLocaleString(), indent: true });
  rows.push({ label: "Less: DSM Penalty", values: gen.map((r) => -r.dsm_loss_mwh), format: (v) => v == null ? "—" : Math.round(v).toLocaleString(), indent: true });
  rows.push({ label: "Net Billable (MWh)", values: gen.map((r) => r.net_billable_mwh), isBold: true, format: (v) => v == null ? "—" : Math.round(v).toLocaleString() });
  rows.push({ label: "Revenue (₹ Cr)", values: gen.map((r) => r.revenue_cr), isBold: true, format: n2 });
  return rows;
}

// Hourly generation tree: Year > Month > Day > Hour (expandable)
// ---------------------------------------------------------------------------

const MONTH_DAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

interface HourlyData {
  solar_hourly?: number[];
  wind_hourly?: number[];
}

function HourlyGenerationSheet({ hourly, codYear }: { hourly: HourlyData; codYear?: number }) {
  const { solar_hourly, wind_hourly } = hourly;
  const hasSolar = solar_hourly && solar_hourly.length > 0;
  const hasWind = wind_hourly && wind_hourly.length > 0;
  const hasData = hasSolar || hasWind;

  // FY labels: if COD is April 2026, FY 2026-27 = Year 1
  const getFyLabel = (yearIndex: number) => {
    const startYear = codYear || new Date().getFullYear();
    const fyStart = startYear + yearIndex;
    const fyEnd = fyStart + 1;
    return `FY ${String(fyStart).slice(-2)}-${String(fyEnd).slice(-2)}`;
  };

  const getMonthLabel = (month: number, yearIndex: number) => {
    const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
    return monthNames[month - 1];
  };

  // Expand state: which years/months/days are expanded
  const [expandedYears, setExpandedYears] = useState<Set<number>>(new Set());
  const [expandedMonths, setExpandedMonths] = useState<Set<string>>(new Set());
  const [expandedDays, setExpandedDays] = useState<Set<string>>(new Set());

  const toggleYear = (yr: number) => setExpandedYears((prev) => {
    const next = new Set(prev);
    if (next.has(yr)) next.delete(yr);
    else next.add(yr);
    return next;
  });

  const toggleMonth = (key: string) => setExpandedMonths((prev) => {
    const next = new Set(prev);
    if (next.has(key)) next.delete(key);
    else next.add(key);
    return next;
  });

  const toggleDay = (key: string) => setExpandedDays((prev) => {
    const next = new Set(prev);
    if (next.has(key)) next.delete(key);
    else next.add(key);
    return next;
  });

  // Helper: get hourly data for a specific year/month/day
  const getYearData = (year: number, isSolar: boolean) => {
    const data = isSolar ? solar_hourly : wind_hourly;
    if (!data) return [];
    const start = (year - 1) * 8760;
    return data.slice(start, start + 8760);
  };

  const getMonthData = (year: number, month: number, isSolar: boolean) => {
    const yearData = getYearData(year, isSolar);
    if (!yearData) return [];
    const start = MONTH_DAYS.slice(0, month - 1).reduce((a, d) => a + d, 0) * 24;
    const days = MONTH_DAYS[month - 1];
    return yearData.slice(start, start + days * 24);
  };

  const getDayData = (year: number, month: number, day: number, isSolar: boolean) => {
    const monthData = getMonthData(year, month, isSolar);
    if (!monthData) return [];
    const start = (day - 1) * 24;
    return monthData.slice(start, start + 24);
  };

  // Compute totals for display
  const computeYearTotal = (year: number, isSolar: boolean) => {
    const d = getYearData(year, isSolar);
    return d.reduce((a, v) => a + v, 0);
  };

  const computeMonthTotal = (year: number, month: number, isSolar: boolean) => {
    const d = getMonthData(year, month, isSolar);
    return d.reduce((a, v) => a + v, 0);
  };

  const computeDayTotal = (year: number, month: number, day: number, isSolar: boolean) => {
    const d = getDayData(year, month, day, isSolar);
    return d.reduce((a, v) => a + v, 0);
  };

  if (!hasData) {
    return <div className="text-muted-foreground p-4">No hourly generation data available</div>;
  }

  // Build tree: Years (1-25), expandable to months, days, hours
  return (
    <div className="space-y-1 text-xs">
      <div className="flex items-center gap-2 pb-2 text-muted-foreground">
        {hasSolar && <span className="text-orange-600">● Solar</span>}
        {hasWind && <span className="text-blue-600">● Wind</span>}
        <span className="text-muted-foreground/60">Click to expand: Year → Month → Day → Hour</span>
      </div>

      {/* Year rows */}
      {[...Array(25)].map((_, i) => {
        const year = i + 1;
        const isYearExpanded = expandedYears.has(year);
        const solarYr = hasSolar ? computeYearTotal(year, true) : 0;
        const windYr = hasWind ? computeYearTotal(year, false) : 0;
        const fyLabel = getFyLabel(i);

        return (
          <div key={year}>
            <button
              onClick={() => toggleYear(year)}
              className="w-full flex items-center gap-2 py-1.5 hover:bg-accent/40 rounded px-2 text-left font-medium"
            >
              <span className="text-[10px] w-4">{isYearExpanded ? "▼" : "▶"}</span>
              <span className="w-20 font-medium">{fyLabel}</span>
              {hasSolar && <span className="text-orange-700 w-24">{Math.round(solarYr).toLocaleString()} MWh</span>}
              {hasWind && <span className="text-blue-700 w-24">{Math.round(windYr).toLocaleString()} MWh</span>}
            </button>

            {/* Month rows (expandable) */}
            {isYearExpanded && [...Array(12)].map((_, mi) => {
              const month = mi + 1;
              const monthKey = `${year}-${month}`;
              const isMonthExpanded = expandedMonths.has(monthKey);
              const solarMo = hasSolar ? computeMonthTotal(year, month, true) : 0;
              const windMo = hasWind ? computeMonthTotal(year, month, false) : 0;
              const daysInMonth = MONTH_DAYS[month - 1];
              const monthLabel = getMonthLabel(month, i);

              return (
                <div key={monthKey} className="ml-4">
                  <button
                    onClick={() => toggleMonth(monthKey)}
                    className="w-full flex items-center gap-2 py-1 hover:bg-accent/30 rounded px-2 text-left"
                  >
                    <span className="text-[10px] w-4">{isMonthExpanded ? "▼" : "▶"}</span>
                    <span className="w-12 text-muted-foreground">{monthLabel}</span>
                    {hasSolar && <span className="text-orange-700/80 w-24">{Math.round(solarMo).toLocaleString()} MWh</span>}
                    {hasWind && <span className="text-blue-700/80 w-24">{Math.round(windMo).toLocaleString()} MWh</span>}
                  </button>

                  {/* Day rows (expandable) */}
                  {isMonthExpanded && [...Array(daysInMonth)].map((_, di) => {
                    const day = di + 1;
                    const dayKey = `${year}-${month}-${day}`;
                    const isDayExpanded = expandedDays.has(dayKey);
                    const solarDy = hasSolar ? computeDayTotal(year, month, day, true) : 0;
                    const windDy = hasWind ? computeDayTotal(year, month, day, false) : 0;

                    return (
                      <div key={dayKey} className="ml-4">
                        <button
                          onClick={() => toggleDay(dayKey)}
                          className="w-full flex items-center gap-2 py-0.5 hover:bg-accent/20 rounded px-2 text-left"
                        >
                          <span className="text-[10px] w-4">{isDayExpanded ? "▼" : "▶"}</span>
                          <span className="w-12 text-muted-foreground/80">{monthLabel} {day}</span>
                          {hasSolar && <span className="text-orange-600/70 w-20">{Math.round(solarDy).toLocaleString()}</span>}
                          {hasWind && <span className="text-blue-600/70 w-20">{Math.round(windDy).toLocaleString()}</span>}
                        </button>

                        {/* Hour values */}
                        {isDayExpanded && (
                          <div className="ml-8 flex flex-wrap gap-0.5 py-1">
                            {[...Array(24)].map((_, h) => {
                              const hour = h;
                              const hourIdx = (day - 1) * 24 + hour;
                              const solarHr = hasSolar ? getDayData(year, month, day, true)[hourIdx % 24] : 0;
                              const windHr = hasWind ? getDayData(year, month, day, false)[hourIdx % 24] : 0;
                              return (
                                <div key={h} className="w-10 text-center text-[9px] border rounded px-0.5">
                                  <span className="text-muted-foreground">{h}:00</span>
                                  {hasSolar && <div className="text-orange-700">{Math.round(solarHr)}</div>}
                                  {hasWind && <div className="text-blue-700">{Math.round(windHr)}</div>}
                                </div>
                              );
                            })}
                          </div>
                        )}
                      </div>
                    );
                  })}
                </div>
              );
            })}
          </div>
        );
      })}
    </div>
  );
}

function buildOpexRows(pnl: PnLRow[]): TableRow[] {
  const total = pnl.map((r) => r.om_cr + r.insurance_cr + r.land_lease_cr + r.am_fee_cr + r.misc_opex_cr);
  return [
    { label: "O&M (₹ Cr)", values: pnl.map((r) => r.om_cr), format: n2 },
    { label: "Insurance (₹ Cr)", values: pnl.map((r) => r.insurance_cr), format: n2, indent: true },
    { label: "Land Lease (₹ Cr)", values: pnl.map((r) => r.land_lease_cr), format: n2, indent: true },
    { label: "AM Fee (₹ Cr)", values: pnl.map((r) => r.am_fee_cr), format: n2, indent: true },
    { label: "Miscellaneous (₹ Cr)", values: pnl.map((r) => r.misc_opex_cr), format: n2, indent: true },
    { label: "Total OPEX (₹ Cr)", values: total, isBold: true, format: n2 },
    { label: "OPEX as % of Revenue", values: pnl.map((r, i) => r.revenue_cr > 0 ? total[i] / r.revenue_cr * 100 : null), format: (v) => v == null ? "—" : `${v.toFixed(1)}%`, indent: true },
  ];
}

function IdcSheet({ idc }: { idc: IdcPhasing }) {
  if (!idc?.base_capex_cr) return <div className="text-muted-foreground p-4">No IDC data available</div>;

  const months = idc.monthly ?? [];
  const nMonths = months.length;
  const nCols = Math.min(nMonths, 24); // Cap at 24 months for display

  // Build ALL-IN-ONE matrix: both component costs AND funding sources
  const monthlyRate = 1 / nMonths;
  const solarPct = 0.70, windPct = 0.0, landPct = 0.10, epcPct = 0.12, contPct = 0.08;

  const matrixRows: TableRow[] = [
    // === Component Costs (what's being built) ===
    { isHeader: true, label: "COMPONENT COSTS", values: [] },
    { label: "Solar Capex", values: Array(nCols).fill(0).map((_, i) => months[i] ? idc.base_capex_cr * solarPct * monthlyRate : 0) },
    { label: "Wind Capex", values: Array(nCols).fill(0).map((_, i) => months[i] ? idc.base_capex_cr * windPct * monthlyRate : 0) },
    { label: "Land & Common", values: Array(nCols).fill(0).map((_, i) => months[i] ? idc.base_capex_cr * landPct * monthlyRate : 0) },
    { label: "EPC Overhead", values: Array(nCols).fill(0).map((_, i) => months[i] ? idc.base_capex_cr * epcPct * monthlyRate : 0) },
    { label: "Contingency", values: Array(nCols).fill(0).map((_, i) => months[i] ? idc.base_capex_cr * contPct * monthlyRate : 0) },
    { isSeparator: true, label: "", values: [] },
    // === Funding Sources (how it's paid) ===
    { isHeader: true, label: "FUNDING SOURCES", values: [] },
    { label: "Equity Draw", values: months.slice(0, nCols).map((m) => m.equity_draw_cr) },
    { label: "Debt Draw", values: months.slice(0, nCols).map((m) => m.debt_draw_cr) },
    { label: "IDC Interest", values: months.slice(0, nCols).map((m) => m.idc_accrual_cr), indent: true },
    { isSeparator: true, label: "", values: [] },
    // === Cumulative (running totals) ===
    { isHeader: true, label: "CUMULATIVE", values: [] },
    { label: "Cum. Equity", values: months.slice(0, nCols).map((m) => m.cum_equity_cr), indent: true },
    { label: "Cum. Debt", values: months.slice(0, nCols).map((m) => m.cum_debt_cr), indent: true },
    { label: "Cum. IDC", values: months.slice(0, nCols).map((m) => m.cum_idc_cr), indent: true },
    { isSeparator: true, label: "", values: [] },
    { label: "Total Project Cost", values: months.slice(0, nCols).map((m) => m.cum_tpc_cr), isBold: true },
  ];

  // Compact header
  const fundingMix = [
    { label: "Base", val: idc.base_capex_cr },
    { label: "IDC", val: idc.idc_cr },
    { label: "Total", val: idc.total_capex_cr },
    { label: "Equity", val: idc.equity_cr },
    { label: "Debt", val: idc.debt_cr },
  ];

  return (
    <div className="space-y-4">
      {/* Header Cards */}
      <div className="grid grid-cols-5 gap-2">
        {fundingMix.map((f) => (
          <div key={f.label} className="border rounded px-3 py-2 text-center">
            <p className="text-[10px] text-muted-foreground">{f.label}</p>
            <p className="text-sm font-bold tabular-nums">₹{f.val.toFixed(0)}</p>
          </div>
        ))}
      </div>

      {/* Single ALL-IN-ONE Matrix Table */}
      <div className="border rounded-lg overflow-hidden">
        <div className="bg-muted/50 px-4 py-2 border-b border-border">
          <h3 className="font-semibold text-sm">IDC Construction Phasing Matrix ({nMonths} months)</h3>
        </div>
        <HorizontalTable years={months.slice(0, nCols).map((m) => m.month)} rows={matrixRows} unit="₹ Cr" yearPrefix="M" />
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Main workbook
// ---------------------------------------------------------------------------

interface Props {
  scenarioId: string;
  kpis: KpiSummary;
  debtScheduleJson: string | null;
  activeSheet: string;
  codYear?: number;
}

export function WorkbookView({ scenarioId, kpis, debtScheduleJson, activeSheet, codYear }: Props) {
  const { data: stmts } = useQuery({
    queryKey: ["statements", scenarioId],
    queryFn: () => getStatements(scenarioId),
  });

  const debtSchedule: DebtYearRow[] = (() => {
    try {
      const safe = (debtScheduleJson ?? "[]")
        .replace(/:\s*Infinity/g, ": null")
        .replace(/:\s*-Infinity/g, ": null")
        .replace(/:\s*NaN\b/g, ": null");
      return JSON.parse(safe) as DebtYearRow[];
    } catch {
      return [];
    }
  })();

  const pnl = stmts?.pnl ?? [];
  const cfs = stmts?.cfs ?? [];
  const bs = stmts?.bs ?? [];
  const generation = stmts?.generation ?? [];
  const idcPhasing = stmts?.idc_phasing;
  const years = pnl.map((r) => r.year);
  const debtYears = debtSchedule.map((r) => r.year);
  const genYears = generation.map((r) => r.year);

  return (
    <div className="space-y-0">
      <p className="text-xs text-muted-foreground mb-4">
        All monetary values in INR Crore unless noted
      </p>

      {activeSheet === "summary" && <SummarySheet kpis={kpis} scenarioId={scenarioId} />}
      {activeSheet === "pnl" && pnl.length > 0 && (
        <HorizontalTable years={years} rows={buildPnLRows(pnl)} />
      )}
      {activeSheet === "cfs" && cfs.length > 0 && (
        <HorizontalTable years={years} rows={buildCfsRows(cfs, kpis, pnl)} />
      )}
      {activeSheet === "bs" && bs.length > 0 && (
        <HorizontalTable years={years} rows={buildBsRows(bs)} />
      )}
      {activeSheet === "debt" && debtSchedule.length > 0 && (
        <HorizontalTable years={debtYears} rows={buildDebtRows(debtSchedule)} />
      )}
      {activeSheet === "irr" && <IrrSheet kpis={kpis} />}
      {activeSheet === "generation" && (stmts?.solar_hourly || stmts?.wind_hourly ? (
        <HourlyGenerationSheet hourly={{ solar_hourly: stmts?.solar_hourly, wind_hourly: stmts?.wind_hourly }} codYear={codYear} />
      ) : generation.length > 0 ? (
        <HorizontalTable years={genYears} rows={buildGenerationRows(generation)} unit="MWh / ₹Cr" />
      ) : (
        <div className="text-muted-foreground p-4">No generation data available</div>
      ))}
      {activeSheet === "idc" && idcPhasing && (
        <IdcSheet idc={idcPhasing} />
      )}
      {activeSheet === "opex" && pnl.length > 0 && (
        <HorizontalTable years={years} rows={buildOpexRows(pnl)} unit="INR Cr" />
      )}
    </div>
  );
}
