"use client";

import type { ReactNode } from "react";

import type { CustomerGridColumn } from "@/app/customer/_lib/customer-grid-columns";
import { cn } from "@/lib/utils";

import type {
  OverallSummaryColumnFilters,
  OverallSummaryRow,
  OverallSummarySortKey,
} from "./schema";
import { formatPct, formatPlain } from "./utils";

export type OverallSummaryColumnKey =
  | "refId"
  | "isin"
  | "name"
  | "bank"
  | "parentBank"
  | "assetClass"
  | "assetType"
  | "industry"
  | "sector"
  | "purchaseDate"
  | "purchaseCurrency"
  | "quantity"
  | "purchasePrice"
  | "purchaseValue"
  | "marketPrice"
  | "marketValue"
  | "gainLoss"
  | "gainLossPct"
  | "reportingCurrency"
  | "fxRate"
  | "purchaseValueRc"
  | "marketValueRc"
  | "differenceRc"
  | "interestDividend"
  | "dividendCoupon"
  | "targetPrice"
  | "targetPct"
  | "country"
  | "bondRating"
  | "maturity"
  | "portfolioPct"
  | "value"
  | "remarks"
  | "currencyDeployed";

export type OverallSummaryColumnDef = CustomerGridColumn & {
  key: OverallSummaryColumnKey;
  align?: "left" | "right";
  sortKey?: OverallSummarySortKey;
  filterKey?: keyof OverallSummaryColumnFilters;
  filterPlaceholder?: string;
  headClassName?: string;
  cellClassName?: string;
  footer?: "label" | "purchaseValue" | "marketValue" | "gainLoss" | "gainLossPct" | "value" | "empty";
};

function PnlText({ value }: { value: number }) {
  const positive = value >= 0;
  return (
    <span
      className={cn(
        "font-medium tabular-nums",
        positive ? "text-emerald-600 dark:text-emerald-400" : "text-red-600 dark:text-red-400",
      )}
    >
      {formatPlain(value)}
    </span>
  );
}

export const OVERALL_SUMMARY_LOCKED_KEYS: OverallSummaryColumnKey[] = [];

export const OVERALL_SUMMARY_COLUMNS: OverallSummaryColumnDef[] = [
  {
    key: "refId",
    label: "Ref. ID",
    sortKey: "refId",
    filterKey: "refId",
    filterPlaceholder: "Ref. ID",
    footer: "label",
  },
  {
    key: "isin",
    label: "ISIN",
    sortKey: "isin",
    filterKey: "isin",
    filterPlaceholder: "ISIN",
    footer: "empty",
  },
  {
    key: "name",
    label: "Name",
    sortKey: "name",
    filterKey: "name",
    filterPlaceholder: "Name",
    headClassName: "min-w-[200px]",
    cellClassName: "max-w-[240px]",
    footer: "empty",
  },
  {
    key: "bank",
    label: "Bank",
    sortKey: "bank",
    filterKey: "bank",
    filterPlaceholder: "Bank",
    footer: "empty",
  },
  {
    key: "parentBank",
    label: "Parent",
    footer: "empty",
  },
  {
    key: "assetClass",
    label: "Asset class",
    sortKey: "assetClass",
    filterKey: "assetClass",
    filterPlaceholder: "Class",
    footer: "empty",
  },
  {
    key: "assetType",
    label: "Asset type",
    sortKey: "assetType",
    filterKey: "assetType",
    filterPlaceholder: "Type",
    headClassName: "min-w-[140px]",
    cellClassName: "max-w-[180px]",
    footer: "empty",
  },
  {
    key: "industry",
    label: "Industry",
    filterKey: "industry",
    filterPlaceholder: "Industry",
    footer: "empty",
  },
  {
    key: "sector",
    label: "Sector",
    filterKey: "sector",
    filterPlaceholder: "Sector",
    footer: "empty",
  },
  {
    key: "purchaseDate",
    label: "Purchase date",
    sortKey: "purchaseDate",
    footer: "empty",
  },
  {
    key: "purchaseCurrency",
    label: "Purchase CCY",
    footer: "empty",
  },
  {
    key: "quantity",
    label: "Qty",
    align: "right",
    footer: "empty",
  },
  {
    key: "purchasePrice",
    label: "Purchase price",
    align: "right",
    footer: "empty",
  },
  {
    key: "purchaseValue",
    label: "Purchase value",
    align: "right",
    footer: "purchaseValue",
  },
  {
    key: "marketPrice",
    label: "Mkt price",
    align: "right",
    footer: "empty",
  },
  {
    key: "marketValue",
    label: "Market value",
    sortKey: "marketValue",
    align: "right",
    footer: "marketValue",
  },
  {
    key: "gainLoss",
    label: "Gain / loss",
    sortKey: "gainLoss",
    align: "right",
    footer: "gainLoss",
  },
  {
    key: "gainLossPct",
    label: "% G/L",
    sortKey: "gainLossPct",
    align: "right",
    footer: "gainLossPct",
  },
  {
    key: "reportingCurrency",
    label: "Rep. CCY",
    footer: "empty",
  },
  {
    key: "fxRate",
    label: "FX rate",
    align: "right",
    footer: "empty",
  },
  {
    key: "purchaseValueRc",
    label: "Purchase RC",
    align: "right",
    footer: "empty",
  },
  {
    key: "marketValueRc",
    label: "Market RC",
    align: "right",
    footer: "empty",
  },
  {
    key: "differenceRc",
    label: "Diff. RC",
    align: "right",
    footer: "empty",
  },
  {
    key: "interestDividend",
    label: "Interest / div.",
    align: "right",
    defaultVisible: false,
    footer: "empty",
  },
  {
    key: "dividendCoupon",
    label: "Div. / coupon",
    defaultVisible: false,
    footer: "empty",
  },
  {
    key: "targetPrice",
    label: "Target price",
    align: "right",
    defaultVisible: false,
    footer: "empty",
  },
  {
    key: "targetPct",
    label: "Target %",
    align: "right",
    defaultVisible: false,
    footer: "empty",
  },
  {
    key: "country",
    label: "Country",
    defaultVisible: false,
    footer: "empty",
  },
  {
    key: "bondRating",
    label: "Bond rating",
    defaultVisible: false,
    footer: "empty",
  },
  {
    key: "maturity",
    label: "Maturity",
    defaultVisible: false,
    footer: "empty",
  },
  {
    key: "portfolioPct",
    label: "% portfolio",
    align: "right",
    footer: "empty",
  },
  {
    key: "value",
    label: "Value",
    sortKey: "value",
    align: "right",
    footer: "value",
  },
  {
    key: "remarks",
    label: "Remarks",
    headClassName: "min-w-[120px]",
    cellClassName: "max-w-[140px]",
    defaultVisible: false,
    footer: "empty",
  },
  {
    key: "currencyDeployed",
    label: "CCY deployed",
    footer: "empty",
  },
];

export function resolveOverallSummaryVisibleColumns(
  order: string[],
  visibility: Record<string, boolean>,
): OverallSummaryColumnDef[] {
  const byKey = new Map(OVERALL_SUMMARY_COLUMNS.map((column) => [column.key, column]));
  const ordered: OverallSummaryColumnDef[] = [];
  for (const key of order) {
    const column = byKey.get(key as OverallSummaryColumnKey);
    if (!column || visibility[column.key] === false) continue;
    ordered.push(column);
  }
  for (const column of OVERALL_SUMMARY_COLUMNS) {
    if (visibility[column.key] === false) continue;
    if (ordered.some((entry) => entry.key === column.key)) continue;
    ordered.push(column);
  }
  return ordered;
}

export function renderOverallSummaryCell(column: OverallSummaryColumnDef, row: OverallSummaryRow): ReactNode {
  switch (column.key) {
    case "refId":
      return (
        <span className="font-semibold">
          {row.refIdDisplay || row.refId}
        </span>
      );
    case "isin":
      return (
        <div className="flex flex-col gap-0.5">
          <span>{row.ticker || row.isin}</span>
          {row.ticker && row.isin && row.isin !== row.ticker ? (
            <span className="text-[10px] text-muted-foreground">{row.isin}</span>
          ) : null}
        </div>
      );
    case "name":
      return <span className="line-clamp-2">{row.name}</span>;
    case "bank":
      return row.bank || "—";
    case "parentBank":
      return row.parentBank || "—";
    case "assetClass":
      return (
        <div className="flex flex-col gap-0.5">
          <span>{row.assetClass || "—"}</span>
          {row.assetClassTag ? (
            <span className="max-w-[120px] truncate text-[10px] text-muted-foreground opacity-70">
              {row.assetClassTag}
            </span>
          ) : null}
        </div>
      );
    case "assetType":
      return <span className="line-clamp-2">{row.assetType || "—"}</span>;
    case "industry":
      return row.industry || "—";
    case "sector":
      return row.sector || "—";
    case "purchaseDate":
      return row.purchaseDate || "—";
    case "purchaseCurrency":
      return row.purchaseCurrency || "—";
    case "quantity":
      return formatPlain(row.quantity, 0);
    case "purchasePrice":
      return formatPlain(row.purchasePrice);
    case "purchaseValue":
      return formatPlain(row.purchaseValue);
    case "marketPrice":
      return formatPlain(row.marketPrice);
    case "marketValue":
      return <span className="font-medium">{formatPlain(row.marketValue)}</span>;
    case "gainLoss":
      return <PnlText value={row.gainLoss} />;
    case "gainLossPct":
      return (
        <span
          className={cn(
            "font-medium tabular-nums",
            row.gainLossPct >= 0 ? "text-emerald-600 dark:text-emerald-400" : "text-red-600 dark:text-red-400",
          )}
        >
          {formatPct(row.gainLossPct)}
        </span>
      );
    case "reportingCurrency":
      return row.reportingCurrency || "—";
    case "fxRate":
      return formatPlain(row.fxRate, 4);
    case "purchaseValueRc":
      return formatPlain(row.purchaseValueRc);
    case "marketValueRc":
      return formatPlain(row.marketValueRc);
    case "differenceRc":
      return <PnlText value={row.differenceRc} />;
    case "interestDividend":
      return row.interestDividend > 0 ? formatPlain(row.interestDividend) : "—";
    case "dividendCoupon":
      return row.dividendCoupon || "—";
    case "targetPrice":
      return row.targetPrice != null ? formatPlain(row.targetPrice) : "—";
    case "targetPct":
      return row.targetPct != null ? `${row.targetPct.toFixed(1)}%` : "—";
    case "country":
      return row.country || "—";
    case "bondRating":
      return row.bondRating || "—";
    case "maturity":
      return row.maturity || "—";
    case "portfolioPct":
      return `${row.portfolioPct.toFixed(2)}%`;
    case "value":
      return <span className="font-semibold">{formatPlain(row.value)}</span>;
    case "remarks": {
      const title = [row.remarks, row.remarksTag].filter(Boolean).join(" · ");
      if (!row.remarks && !row.remarksTag) return "—";
      return (
        <div className="flex flex-col gap-0.5" title={title}>
          {row.remarks ? <span className="truncate">{row.remarks}</span> : null}
          {row.remarksTag ? <span className="truncate text-[10px] opacity-70">{row.remarksTag}</span> : null}
        </div>
      );
    }
    case "currencyDeployed":
      return <span className="font-medium">{row.currencyDeployed || "—"}</span>;
    default:
      return "—";
  }
}

export function renderOverallSummaryFooterCell(
  column: OverallSummaryColumnDef,
  pageTotals: {
    count: number;
    purchaseValue: number;
    marketValue: number;
    gainLoss: number;
    gainLossPct: number;
    value: number;
  },
  labelColSpan: number,
): { content: ReactNode; colSpan?: number; className?: string } | null {
  switch (column.footer) {
    case "label":
      return {
        content: `Page totals (${pageTotals.count} positions)`,
        colSpan: labelColSpan,
        className: "py-3 pl-4 text-sm",
      };
    case "purchaseValue":
      return {
        content: formatPlain(pageTotals.purchaseValue),
        className: "py-3 text-right text-sm tabular-nums",
      };
    case "marketValue":
      return {
        content: formatPlain(pageTotals.marketValue),
        className: "py-3 text-right text-sm tabular-nums",
      };
    case "gainLoss":
      return {
        content: <PnlText value={pageTotals.gainLoss} />,
        className: "py-3 text-right text-sm",
      };
    case "gainLossPct":
      return {
        content: (
          <span
            className={cn(
              "font-medium tabular-nums",
              pageTotals.gainLossPct >= 0 ? "text-emerald-600" : "text-red-600",
            )}
          >
            {formatPct(pageTotals.gainLossPct)}
          </span>
        ),
        className: "py-3 text-right text-sm",
      };
    case "value":
      return {
        content: formatPlain(pageTotals.value),
        className: "py-3 text-right text-sm tabular-nums",
      };
    default:
      return {
        content: null,
        className: "py-3",
      };
  }
}
