import { auth } from "@/auth";
import { redirect, notFound } from "next/navigation";
import Link from "next/link";
import type { Metadata } from "next";
import { hasPermission } from "@/lib/permissions";
import { formatCurrency, formatCompactINR } from "@/lib/utils";
import {
  getReportDataset,
  buildAccountIndex,
  accountNodeSpend,
  accountNodeWeekly,
  costCentresForAccount,
  childBreakdown,
  parseGranularity,
  resolveFy,
  resolveMonth,
  fyLabel,
  FY_MONTHS,
  WEEK_LABELS,
} from "@/lib/reports";
import { ReportsToolbar } from "@/components/reports/reports-toolbar";
import { TrendChart, BreakdownChart } from "@/components/reports/charts";
import { SERIES_COLORS } from "@/lib/report-colors";
import { Kpi, KpiStrip } from "@/components/reports/kpi";
import { ReportBreadcrumb, ReportTitle, SegLink } from "@/components/reports/report-header";

export const metadata: Metadata = { title: "Accounting Code — Reports" };

const sum = (a: number[]) => a.reduce((x, y) => x + y, 0);
const tierBadgeCls: Record<string, string> = {
  Heading: "bg-primary-50 text-primary-700",
  "Sub-heading": "bg-violet-50 text-violet-700",
  Leaf: "bg-neutral-100 text-neutral-600",
};

export default async function AccountingCodeDetail({
  params,
  searchParams,
}: {
  params: Promise<{ id: string }>;
  searchParams: Promise<{ fy?: string; gran?: string; month?: string; break?: string; topn?: string }>;
}) {
  const session = await auth();
  if (!session?.user) return null;
  if (!hasPermission(session.user.role, "view_analytics")) redirect("/dashboard");

  const { id } = await params;
  const sp = await searchParams;
  const ds = await getReportDataset();
  const idx = buildAccountIndex(ds.accounts);
  const node = idx.byId.get(id);
  if (!node) notFound();

  const gran = parseGranularity(sp.gran);
  const fy = resolveFy(ds, sp.fy);
  const yearly = gran === "yearly";
  const weekly = gran === "weekly";
  const month = resolveMonth(ds, fy, sp.month);
  const unit = yearly ? "year" : weekly ? "week" : "month";
  const leaf = idx.isLeaf(id);
  const topn = sp.topn === "10" ? 10 : sp.topn === "all" ? 9999 : 5;
  const breakMode = leaf ? "cc" : sp.break === "cc" ? "cc" : "children";

  const spend = accountNodeSpend(ds, idx, id, fy);
  const monthLabel = (i: number) => `${FY_MONTHS[i]} '${String((fy + (i >= 9 ? 1 : 0)) % 100).padStart(2, "0")}`;
  const series = yearly
    ? ds.fys.map((y, i) => ({ label: fyLabel(y), value: spend.fyTotals[i] }))
    : weekly
      ? WEEK_LABELS.map((w, i) => ({ label: w, value: accountNodeWeekly(ds, idx, id, fy, month)[i] }))
      : FY_MONTHS.map((m, i) => ({ label: m, value: spend.months[i] }));
  const total = sum(series.map((s) => s.value));
  const avg = series.length ? total / series.length : 0;
  const peak = series.reduce((best, s) => (s.value > best.value ? s : best), series[0] ?? { label: "—", value: 0 });
  const nf = ds.fys.length;
  const yoy = nf >= 2 && spend.fyTotals[nf - 2] ? ((spend.fyTotals[nf - 1] - spend.fyTotals[nf - 2]) / spend.fyTotals[nf - 2]) * 100 : 0;

  const childTier = idx.childrenOf(id)[0]?.tier ?? "Sub-heading";
  const breakdown = (breakMode === "cc" ? costCentresForAccount(ds, idx, id, fy) : childBreakdown(ds, idx, id, fy)).slice(0, topn);
  const breakTotal = sum(breakdown.map((b) => b.value)) || 1;
  const breakLabel = breakMode === "cc" ? "Cost centre" : childTier;
  const breakTitle = breakMode === "cc" ? "Top cost centres" : "Composition by sub-account";

  const periodLabel = yearly ? `${ds.fys.length} FYs` : weekly ? `${monthLabel(month)} · ${fyLabel(fy)}` : fyLabel(fy);
  const base = `/reports/accounting-codes/${id}`;
  const q = (extra: Record<string, string>) => {
    const p = new URLSearchParams({ fy: String(fy), gran });
    if (weekly) p.set("month", String(month));
    for (const [k, v] of Object.entries(extra)) p.set(k, v);
    return `${base}?${p.toString()}`;
  };
  const exportHref = `/api/reports/spend?dim=accounting-code-detail&id=${id}&fy=${fy}&gran=${gran}&break=${breakMode}`;

  const path = idx.pathTo(id);
  const trail = [
    { label: "Accounting Codes", href: `/reports/accounting-codes?fy=${fy}&gran=${gran}` },
    ...path.map((a, i) => ({
      label: `${a.code} · ${a.name}`,
      href: i < path.length - 1 ? `/reports/accounting-codes?fy=${fy}&gran=${gran}&parent=${a.id}` : undefined,
    })),
  ];

  return (
    <div>
      <ReportBreadcrumb trail={trail} />
      <ReportsToolbar
        fys={ds.fys}
        fy={fy}
        gran={gran}
        month={month}
        monthOptions={FY_MONTHS.map((_, i) => ({ value: i, label: monthLabel(i) }))}
        exportHref={exportHref}
      />

      <Link
        href={node.parentId ? `/reports/accounting-codes?fy=${fy}&gran=${gran}&parent=${node.parentId}` : `/reports/accounting-codes?fy=${fy}&gran=${gran}`}
        className="mb-4 inline-flex items-center gap-1.5 text-sm font-medium text-primary-600 hover:text-primary-700"
      >
        ← Back to Accounting Codes
      </Link>

      <ReportTitle
        title={`${node.code} · ${node.name}`}
        subtitle={`Aggregates all spend under this ${node.tier.toLowerCase()} · ${periodLabel}`}
        badge={<span className={`rounded-full px-2.5 py-0.5 text-xs font-medium ${tierBadgeCls[node.tier]}`}>{node.tier}</span>}
      />

      <KpiStrip>
        <Kpi label="Total spend" value={formatCompactINR(total)} sub={periodLabel} />
        <Kpi label={`Avg / ${unit}`} value={formatCompactINR(avg)} />
        <Kpi label={`Peak ${unit}`} value={peak.label} sub={formatCompactINR(peak.value)} />
        <Kpi label="YoY change" value={`${yoy >= 0 ? "+" : ""}${yoy.toFixed(1)}%`} sub="vs prior FY" delta={yoy} />
      </KpiStrip>

      <div className="mb-6 rounded-lg border border-neutral-200 bg-white p-5">
        <p className="mb-4 text-sm font-semibold text-neutral-900">Spend trend</p>
        <TrendChart kind={yearly ? "bar" : "line"} data={series} />
      </div>

      <div className="rounded-lg border border-neutral-200 bg-white p-5">
        <div className="mb-4 flex flex-wrap items-center justify-between gap-3">
          <p className="text-sm font-semibold text-neutral-900">{breakTitle}</p>
          <div className="flex flex-wrap items-center gap-3">
            {!leaf && (
              <SegLink
                label="Break down by"
                options={[{ value: "children", label: `${childTier}s` }, { value: "cc", label: "Cost centres" }]}
                current={breakMode}
                hrefFor={(v) => q({ break: v, topn: sp.topn ?? "5" })}
              />
            )}
            <SegLink
              label="Top"
              options={[{ value: "5", label: "5" }, { value: "10", label: "10" }, { value: "all", label: "All" }]}
              current={sp.topn === "10" ? "10" : sp.topn === "all" ? "all" : "5"}
              hrefFor={(v) => q({ break: breakMode, topn: v })}
            />
          </div>
        </div>
        {breakdown.length === 0 ? (
          <p className="py-8 text-center text-sm text-neutral-400">No spend to break down for {periodLabel}.</p>
        ) : (
          <div className="grid grid-cols-1 gap-6 lg:grid-cols-5">
            <div className="lg:col-span-3">
              <BreakdownChart data={breakdown} />
            </div>
            <div className="lg:col-span-2">
              <table className="w-full text-sm">
                <thead className="border-b border-neutral-200 text-left text-xs font-semibold uppercase tracking-wider text-neutral-400">
                  <tr>
                    <th className="py-2">{breakLabel}</th>
                    <th className="py-2 text-right">Spend</th>
                    <th className="py-2 text-right">%</th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-neutral-100">
                  {breakdown.map((b, i) => (
                    <tr key={b.id}>
                      <td className="py-2">
                        <span className="mr-2 inline-block h-2.5 w-2.5 rounded-sm align-middle" style={{ background: SERIES_COLORS[i % SERIES_COLORS.length] }} />
                        {b.label}
                      </td>
                      <td className="py-2 text-right font-medium tabular-nums">{formatCurrency(b.value)}</td>
                      <td className="py-2 text-right tabular-nums text-neutral-500">{((b.value / breakTotal) * 100).toFixed(0)}%</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}
