import { Fragment, useState } from "react";
import { useTranslation } from "react-i18next";
import { ArrowUpDown } from "lucide-react";
import type { CategoryDelta } from "../../shared/types";
import { reorderRows } from "../../utils/reorderRows";

export interface ComparePeriodTableProps {
  rows: CategoryDelta[];
  /** Label for the "previous" monthly column (e.g. "March 2026" or "2025"). */
  previousLabel: string;
  /** Label for the "current" monthly column (e.g. "April 2026" or "2026"). */
  currentLabel: string;
  /** Optional label for the previous cumulative window (YTD). Falls back to previousLabel. */
  cumulativePreviousLabel?: string;
  /** Optional label for the current cumulative window (YTD). Falls back to currentLabel. */
  cumulativeCurrentLabel?: string;
}

function formatCurrency(amount: number, language: string): string {
  return new Intl.NumberFormat(language === "fr" ? "fr-CA" : "en-CA", {
    style: "currency",
    currency: "CAD",
    maximumFractionDigits: 0,
  }).format(amount);
}

function formatSignedCurrency(amount: number, language: string): string {
  return new Intl.NumberFormat(language === "fr" ? "fr-CA" : "en-CA", {
    style: "currency",
    currency: "CAD",
    maximumFractionDigits: 0,
    signDisplay: "always",
  }).format(amount);
}

function formatPct(pct: number | null, language: string): string {
  if (pct === null) return "—";
  return new Intl.NumberFormat(language === "fr" ? "fr-CA" : "en-CA", {
    style: "percent",
    maximumFractionDigits: 1,
    signDisplay: "always",
  }).format(pct / 100);
}

function variationColor(value: number): string {
  // Compare report deals with expenses (abs values): spending more is negative
  // for the user, spending less is positive. Mirror that colour convention
  // consistently so the eye parses the delta sign at a glance.
  if (value > 0) return "var(--negative, #ef4444)";
  if (value < 0) return "var(--positive, #10b981)";
  return "";
}

const STORAGE_KEY = "compare-subtotals-position";

type SectionType = "expense" | "income" | "transfer";

/** Aggregate of the 6 comparable figures across a set of leaf rows. */
interface Totals {
  monthCurrent: number;
  monthPrevious: number;
  monthDelta: number;
  ytdCurrent: number;
  ytdPrevious: number;
  ytdDelta: number;
}

function sumLeaves(rows: CategoryDelta[]): Totals {
  return rows
    .filter((r) => !r.is_parent)
    .reduce<Totals>(
      (acc, r) => ({
        monthCurrent: acc.monthCurrent + r.currentAmount,
        monthPrevious: acc.monthPrevious + r.previousAmount,
        monthDelta: acc.monthDelta + r.deltaAbs,
        ytdCurrent: acc.ytdCurrent + r.cumulativeCurrentAmount,
        ytdPrevious: acc.ytdPrevious + r.cumulativePreviousAmount,
        ytdDelta: acc.ytdDelta + r.cumulativeDeltaAbs,
      }),
      { monthCurrent: 0, monthPrevious: 0, monthDelta: 0, ytdCurrent: 0, ytdPrevious: 0, ytdDelta: 0 },
    );
}

function pct(delta: number, previous: number): number | null {
  return previous !== 0 ? (delta / Math.abs(previous)) * 100 : null;
}

export default function ComparePeriodTable({
  rows,
  previousLabel,
  currentLabel,
  cumulativePreviousLabel,
  cumulativeCurrentLabel,
}: ComparePeriodTableProps) {
  const { t, i18n } = useTranslation();
  const lang = i18n.language;

  const [subtotalsOnTop, setSubtotalsOnTop] = useState(() => {
    const stored = localStorage.getItem(STORAGE_KEY);
    return stored === null ? true : stored === "top";
  });
  const toggleSubtotals = () => {
    setSubtotalsOnTop((prev) => {
      const next = !prev;
      localStorage.setItem(STORAGE_KEY, next ? "top" : "bottom");
      return next;
    });
  };

  const monthPrevLabel = previousLabel;
  const monthCurrLabel = currentLabel;
  const ytdPrevLabel = cumulativePreviousLabel ?? previousLabel;
  const ytdCurrLabel = cumulativeCurrentLabel ?? currentLabel;

  // Group rows into contiguous type sections (the service already type-sorts).
  const sectionLabels: Record<SectionType, string> = {
    expense: t("reports.compare.sections.expenses"),
    income: t("reports.compare.sections.income"),
    transfer: t("reports.compare.sections.transfers"),
  };
  const sectionTotalKeys: Record<SectionType, string> = {
    expense: "reports.compare.totalExpenses",
    income: "reports.compare.totalIncome",
    transfer: "reports.compare.totalTransfers",
  };
  const sections: { type: SectionType; rows: CategoryDelta[] }[] = [];
  let currentType: SectionType | null = null;
  for (const row of rows) {
    const type = (row.category_type ?? "expense") as SectionType;
    if (type !== currentType) {
      currentType = type;
      sections.push({ type, rows: [] });
    }
    sections[sections.length - 1].rows.push(row);
  }

  // Grand totals across every leaf.
  const totals = sumLeaves(rows);

  return (
    <div className="bg-[var(--card)] border border-[var(--border)] rounded-xl overflow-hidden">
      <div className="flex justify-end px-3 py-2 border-b border-[var(--border)]">
        <button
          onClick={toggleSubtotals}
          className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-lg text-xs font-medium text-[var(--muted-foreground)] hover:bg-[var(--muted)] transition-colors"
        >
          <ArrowUpDown size={13} />
          {subtotalsOnTop ? t("reports.subtotalsOnTop") : t("reports.subtotalsOnBottom")}
        </button>
      </div>
      <div className="overflow-x-auto overflow-y-auto" style={{ maxHeight: "calc(100vh - 220px)" }}>
        <table className="w-full text-sm">
          <thead className="sticky top-0 z-20">
            <tr className="border-b border-[var(--border)] bg-[var(--card)]">
              <th
                rowSpan={2}
                className="text-left px-3 py-2 font-medium text-[var(--muted-foreground)] align-bottom sticky left-0 bg-[var(--card)] z-30 min-w-[180px]"
              >
                {t("reports.highlights.category")}
              </th>
              <th
                colSpan={4}
                className="text-center px-3 py-1 font-medium text-[var(--muted-foreground)] border-l border-[var(--border)] bg-[var(--card)]"
              >
                {t("reports.bva.monthly")}
              </th>
              <th
                colSpan={4}
                className="text-center px-3 py-1 font-medium text-[var(--muted-foreground)] border-l border-[var(--border)] bg-[var(--card)]"
              >
                {t("reports.bva.ytd")}
              </th>
            </tr>
            <tr className="border-b border-[var(--border)] bg-[var(--card)]">
              <th className="text-right px-3 py-1 font-medium text-[var(--muted-foreground)] border-l border-[var(--border)] bg-[var(--card)]">
                <div>{t("reports.compare.currentAmount")}</div>
                <div className="text-[10px] font-normal opacity-70">{monthCurrLabel}</div>
              </th>
              <th className="text-right px-3 py-1 font-medium text-[var(--muted-foreground)] bg-[var(--card)]">
                <div>{t("reports.compare.previousAmount")}</div>
                <div className="text-[10px] font-normal opacity-70">{monthPrevLabel}</div>
              </th>
              <th className="text-right px-3 py-1 font-medium text-[var(--muted-foreground)] bg-[var(--card)]">
                {t("reports.bva.dollarVar")}
              </th>
              <th className="text-right px-3 py-1 font-medium text-[var(--muted-foreground)] bg-[var(--card)]">
                {t("reports.bva.pctVar")}
              </th>
              <th className="text-right px-3 py-1 font-medium text-[var(--muted-foreground)] border-l border-[var(--border)] bg-[var(--card)]">
                <div>{t("reports.compare.currentAmount")}</div>
                <div className="text-[10px] font-normal opacity-70">{ytdCurrLabel}</div>
              </th>
              <th className="text-right px-3 py-1 font-medium text-[var(--muted-foreground)] bg-[var(--card)]">
                <div>{t("reports.compare.previousAmount")}</div>
                <div className="text-[10px] font-normal opacity-70">{ytdPrevLabel}</div>
              </th>
              <th className="text-right px-3 py-1 font-medium text-[var(--muted-foreground)] bg-[var(--card)]">
                {t("reports.bva.dollarVar")}
              </th>
              <th className="text-right px-3 py-1 font-medium text-[var(--muted-foreground)] bg-[var(--card)]">
                {t("reports.bva.pctVar")}
              </th>
            </tr>
          </thead>
          <tbody>
            {rows.length === 0 ? (
              <tr>
                <td colSpan={9} className="px-3 py-4 text-center text-[var(--muted-foreground)] italic">
                  {t("reports.empty.noData")}
                </td>
              </tr>
            ) : (
              <>
                {sections.map((section) => {
                  const sectionTotals = sumLeaves(section.rows);
                  return (
                    <Fragment key={section.type}>
                      <tr className="bg-[var(--muted)]">
                        <td
                          colSpan={9}
                          className="px-3 py-1.5 font-semibold text-[var(--muted-foreground)] uppercase text-xs tracking-wider sticky left-0 bg-[var(--muted)]"
                        >
                          {sectionLabels[section.type]}
                        </td>
                      </tr>
                      {reorderRows(section.rows, subtotalsOnTop).map((row) => {
                        const isParent = row.is_parent ?? false;
                        const depth = row.depth ?? 0;
                        const isTopParent = isParent && depth === 0;
                        const isIntermediateParent = isParent && depth >= 1;
                        const paddingClass =
                          depth >= 3 ? "pl-20" : depth === 2 ? "pl-14" : depth === 1 ? "pl-8" : "px-3";
                        return (
                          <tr
                            key={`${row.categoryId ?? "uncat"}-${isParent}-${depth}-${row.categoryName}`}
                            className={`border-b border-[var(--border)]/50 ${
                              isTopParent
                                ? "bg-[color-mix(in_srgb,var(--muted)_30%,var(--card))] font-semibold"
                                : isIntermediateParent
                                  ? "bg-[color-mix(in_srgb,var(--muted)_15%,var(--card))] font-medium"
                                  : "hover:bg-[var(--muted)]/40"
                            }`}
                          >
                            <td
                              className={`py-1.5 sticky left-0 z-10 ${
                                isTopParent
                                  ? "px-3 bg-[color-mix(in_srgb,var(--muted)_30%,var(--card))]"
                                  : isIntermediateParent
                                    ? `${paddingClass} bg-[color-mix(in_srgb,var(--muted)_15%,var(--card))]`
                                    : `${paddingClass} bg-[var(--card)]`
                              }`}
                            >
                              <span className="flex items-center gap-2">
                                <span
                                  className="w-2.5 h-2.5 rounded-full shrink-0"
                                  style={{ backgroundColor: row.categoryColor }}
                                />
                                {row.categoryName}
                              </span>
                            </td>
                            {/* Monthly block */}
                            <td className="text-right px-3 py-1.5 border-l border-[var(--border)]/50 tabular-nums">
                              {formatCurrency(row.currentAmount, lang)}
                            </td>
                            <td className="text-right px-3 py-1.5 tabular-nums">
                              {formatCurrency(row.previousAmount, lang)}
                            </td>
                            <td
                              className="text-right px-3 py-1.5 tabular-nums font-medium"
                              style={{ color: variationColor(row.deltaAbs) }}
                            >
                              {formatSignedCurrency(row.deltaAbs, lang)}
                            </td>
                            <td
                              className="text-right px-3 py-1.5 tabular-nums"
                              style={{ color: variationColor(row.deltaAbs) }}
                            >
                              {formatPct(row.deltaPct, lang)}
                            </td>
                            {/* Cumulative YTD block */}
                            <td className="text-right px-3 py-1.5 border-l border-[var(--border)]/50 tabular-nums">
                              {formatCurrency(row.cumulativeCurrentAmount, lang)}
                            </td>
                            <td className="text-right px-3 py-1.5 tabular-nums">
                              {formatCurrency(row.cumulativePreviousAmount, lang)}
                            </td>
                            <td
                              className="text-right px-3 py-1.5 tabular-nums font-medium"
                              style={{ color: variationColor(row.cumulativeDeltaAbs) }}
                            >
                              {formatSignedCurrency(row.cumulativeDeltaAbs, lang)}
                            </td>
                            <td
                              className="text-right px-3 py-1.5 tabular-nums"
                              style={{ color: variationColor(row.cumulativeDeltaAbs) }}
                            >
                              {formatPct(row.cumulativeDeltaPct, lang)}
                            </td>
                          </tr>
                        );
                      })}
                      {/* Section net total */}
                      <tr className="border-b border-[var(--border)] bg-[color-mix(in_srgb,var(--muted)_40%,var(--card))] font-semibold text-sm">
                        <td className="px-3 py-2.5 sticky left-0 bg-[color-mix(in_srgb,var(--muted)_40%,var(--card))] z-10">
                          {t(sectionTotalKeys[section.type])}
                        </td>
                        <td className="text-right px-3 py-2.5 border-l border-[var(--border)]/50 tabular-nums">
                          {formatCurrency(sectionTotals.monthCurrent, lang)}
                        </td>
                        <td className="text-right px-3 py-2.5 tabular-nums">
                          {formatCurrency(sectionTotals.monthPrevious, lang)}
                        </td>
                        <td
                          className="text-right px-3 py-2.5 tabular-nums"
                          style={{ color: variationColor(sectionTotals.monthDelta) }}
                        >
                          {formatSignedCurrency(sectionTotals.monthDelta, lang)}
                        </td>
                        <td
                          className="text-right px-3 py-2.5 tabular-nums"
                          style={{ color: variationColor(sectionTotals.monthDelta) }}
                        >
                          {formatPct(pct(sectionTotals.monthDelta, sectionTotals.monthPrevious), lang)}
                        </td>
                        <td className="text-right px-3 py-2.5 border-l border-[var(--border)]/50 tabular-nums">
                          {formatCurrency(sectionTotals.ytdCurrent, lang)}
                        </td>
                        <td className="text-right px-3 py-2.5 tabular-nums">
                          {formatCurrency(sectionTotals.ytdPrevious, lang)}
                        </td>
                        <td
                          className="text-right px-3 py-2.5 tabular-nums"
                          style={{ color: variationColor(sectionTotals.ytdDelta) }}
                        >
                          {formatSignedCurrency(sectionTotals.ytdDelta, lang)}
                        </td>
                        <td
                          className="text-right px-3 py-2.5 tabular-nums"
                          style={{ color: variationColor(sectionTotals.ytdDelta) }}
                        >
                          {formatPct(pct(sectionTotals.ytdDelta, sectionTotals.ytdPrevious), lang)}
                        </td>
                      </tr>
                    </Fragment>
                  );
                })}
                {/* Grand totals row */}
                <tr className="border-t-2 border-[var(--border)] font-bold text-sm bg-[color-mix(in_srgb,var(--muted)_20%,var(--card))]">
                  <td className="px-3 py-3 sticky left-0 bg-[color-mix(in_srgb,var(--muted)_20%,var(--card))] z-10">
                    {t("reports.compare.totalRow")}
                  </td>
                  <td className="text-right px-3 py-3 border-l border-[var(--border)]/50 tabular-nums">
                    {formatCurrency(totals.monthCurrent, lang)}
                  </td>
                  <td className="text-right px-3 py-3 tabular-nums">
                    {formatCurrency(totals.monthPrevious, lang)}
                  </td>
                  <td
                    className="text-right px-3 py-3 tabular-nums"
                    style={{ color: variationColor(totals.monthDelta) }}
                  >
                    {formatSignedCurrency(totals.monthDelta, lang)}
                  </td>
                  <td
                    className="text-right px-3 py-3 tabular-nums"
                    style={{ color: variationColor(totals.monthDelta) }}
                  >
                    {formatPct(pct(totals.monthDelta, totals.monthPrevious), lang)}
                  </td>
                  <td className="text-right px-3 py-3 border-l border-[var(--border)]/50 tabular-nums">
                    {formatCurrency(totals.ytdCurrent, lang)}
                  </td>
                  <td className="text-right px-3 py-3 tabular-nums">
                    {formatCurrency(totals.ytdPrevious, lang)}
                  </td>
                  <td
                    className="text-right px-3 py-3 tabular-nums"
                    style={{ color: variationColor(totals.ytdDelta) }}
                  >
                    {formatSignedCurrency(totals.ytdDelta, lang)}
                  </td>
                  <td
                    className="text-right px-3 py-3 tabular-nums"
                    style={{ color: variationColor(totals.ytdDelta) }}
                  >
                    {formatPct(pct(totals.ytdDelta, totals.ytdPrevious), lang)}
                  </td>
                </tr>
              </>
            )}
          </tbody>
        </table>
      </div>
    </div>
  );
}
