"use client";

import { AlertTriangle, ExternalLink } from "lucide-react";
import * as React from "react";

import { Badge } from "@/components/ui/badge";
import { Checkbox } from "@/components/ui/checkbox";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";

import { SCOPE_DESCRIPTIONS, SCOPE_LABELS, type PreviewRow } from "../_lib/schema";

type Props = {
  rows: PreviewRow[];
  selectedIds: Set<number>;
  onToggle: (id: number, selected: boolean) => void;
  onToggleAll: (selected: boolean) => void;
  readOnly?: boolean;
};

const NUMBER_FORMAT = new Intl.NumberFormat("en-GB", {
  minimumFractionDigits: 2,
  maximumFractionDigits: 6,
});

function formatValue(value: number | null): string {
  return value === null ? "—" : NUMBER_FORMAT.format(value);
}

/**
 * Underlying legs store no amount column, so their value is quantity x price.
 * That figure is shown in muted type to keep it visibly distinct from a stored
 * amount — it is never written back to the row.
 */
function AmountCell({
  amount,
  derived,
}: {
  amount: number | null;
  derived: number | null;
}) {
  if (amount !== null) {
    return <>{formatValue(amount)}</>;
  }

  if (derived === null) {
    return <>—</>;
  }

  return (
    <Tooltip>
      <TooltipTrigger asChild>
        <span className="text-muted-foreground underline decoration-dotted">
          {formatValue(derived)}
        </span>
      </TooltipTrigger>
      <TooltipContent>
        Quantity x purchase price. This leg has no stored amount, so nothing is
        written to that column.
      </TooltipContent>
    </Tooltip>
  );
}

/**
 * The Bulk Edit output list: one row per affected record, Old beside New.
 *
 * Rows are grouped by scope so the operator can see at a glance that a
 * structure-master change is small and bounded while a TRX change reaches live
 * client holdings.
 */
export function PreviewTable({
  rows,
  selectedIds,
  onToggle,
  onToggleAll,
  readOnly = false,
}: Props) {
  const grouped = React.useMemo(() => {
    const buckets: Record<string, PreviewRow[]> = { master: [], temp: [], trx: [] };
    for (const row of rows) {
      buckets[row.scope]?.push(row);
    }
    return buckets;
  }, [rows]);

  const selectableIds = React.useMemo(
    () => rows.filter((row) => !row.applied).map((row) => row.id),
    [rows],
  );
  const allSelected =
    selectableIds.length > 0 && selectableIds.every((id) => selectedIds.has(id));
  const someSelected = selectableIds.some((id) => selectedIds.has(id));

  if (rows.length === 0) {
    return (
      <div className="rounded-lg border bg-card p-8 text-center text-muted-foreground text-sm">
        No records match this underlying and date range.
      </div>
    );
  }

  return (
    <div className="overflow-x-auto rounded-lg border bg-card">
      <Table>
        <TableHeader className="bg-muted/15">
          <TableRow>
            <TableHead rowSpan={2} className="w-10 px-3 align-bottom">
              {!readOnly ? (
                <Checkbox
                  aria-label="Select all rows"
                  checked={allSelected ? true : someSelected ? "indeterminate" : false}
                  onCheckedChange={(checked) => onToggleAll(checked === true)}
                />
              ) : null}
            </TableHead>
            <TableHead rowSpan={2} className="px-3 align-bottom whitespace-nowrap">
              Structure / Record
            </TableHead>
            <TableHead rowSpan={2} className="px-3 align-bottom whitespace-nowrap">
              Date
            </TableHead>
            <TableHead
              colSpan={4}
              className="border-l px-3 text-center font-medium whitespace-nowrap"
            >
              Old
            </TableHead>
            <TableHead
              colSpan={4}
              className="border-l px-3 text-center font-medium whitespace-nowrap"
            >
              New
            </TableHead>
          </TableRow>
          <TableRow>
            <TableHead className="border-l px-3 text-right text-xs">Quantity</TableHead>
            <TableHead className="px-3 text-right text-xs">Purchase Price</TableHead>
            <TableHead className="px-3 text-right text-xs">Initial Level</TableHead>
            <TableHead className="px-3 text-right text-xs">Amount</TableHead>
            <TableHead className="border-l px-3 text-right text-xs">Quantity</TableHead>
            <TableHead className="px-3 text-right text-xs">Purchase Price</TableHead>
            <TableHead className="px-3 text-right text-xs">Initial Level</TableHead>
            <TableHead className="px-3 text-right text-xs">Amount</TableHead>
          </TableRow>
        </TableHeader>
        <TableBody>
          {(["master", "temp", "trx"] as const).map((scope) => {
            const scopeRows = grouped[scope];
            if (!scopeRows?.length) return null;

            return (
              <React.Fragment key={scope}>
                <TableRow className="bg-muted/30 hover:bg-muted/30">
                  <TableCell colSpan={11} className="px-3 py-2">
                    <div className="flex items-center gap-2">
                      <span className="font-medium text-sm">{SCOPE_LABELS[scope]}</span>
                      <Badge variant="secondary">{scopeRows.length}</Badge>
                      <span className="text-muted-foreground text-xs">
                        {SCOPE_DESCRIPTIONS[scope]}
                      </span>
                    </div>
                  </TableCell>
                </TableRow>
                {scopeRows.map((row) => (
                  <PreviewTableRow
                    key={row.id}
                    row={row}
                    selected={selectedIds.has(row.id)}
                    onToggle={onToggle}
                    readOnly={readOnly}
                  />
                ))}
              </React.Fragment>
            );
          })}
        </TableBody>
      </Table>
    </div>
  );
}

function PreviewTableRow({
  row,
  selected,
  onToggle,
  readOnly,
}: {
  row: PreviewRow;
  selected: boolean;
  onToggle: (id: number, selected: boolean) => void;
  readOnly: boolean;
}) {
  return (
    <TableRow className={cn("hover:bg-muted/30", row.applied && "opacity-60")}>
      <TableCell className="px-3">
        {!readOnly && !row.applied ? (
          <Checkbox
            aria-label={`Select record ${row.recordId}`}
            checked={selected}
            onCheckedChange={(checked) => onToggle(row.id, checked === true)}
          />
        ) : null}
      </TableCell>
      <TableCell className="px-3 text-sm">
        <div className="flex flex-col gap-0.5">
          <span className="font-medium">{row.structureIsin ?? row.tableName}</span>

          {row.customerName ? (
            <span className="text-xs">
              {row.customerSubdomain && row.structureIsin ? (
                <a
                  href={`/customer/${row.customerSubdomain}/structure?parentIsin=${encodeURIComponent(row.structureIsin)}`}
                  target="_blank"
                  rel="noreferrer"
                  className="inline-flex items-center gap-1 font-medium text-primary hover:underline"
                >
                  {row.customerName}
                  <ExternalLink className="size-3" />
                </a>
              ) : (
                <span className="font-medium">{row.customerName}</span>
              )}
            </span>
          ) : null}

          <span className="text-muted-foreground text-xs">
            {row.tableName} #{row.recordId}
            {row.customerId ? ` · customer ${row.customerId}` : ""}
            {row.fType ? ` · ${row.fType}` : ""}
          </span>
          {row.schemaName ? (
            <span className="font-mono text-[11px] text-muted-foreground">
              {row.schemaName}
            </span>
          ) : null}
          {row.applied ? (
            <Badge variant="secondary" className="mt-1 w-fit">
              Applied
            </Badge>
          ) : null}
          {row.previouslyAppliedActionId ? (
            <Tooltip>
              <TooltipTrigger asChild>
                <Badge
                  variant="secondary"
                  className="mt-1 w-fit bg-amber-500/15 text-amber-700 dark:text-amber-400"
                >
                  Already split by #{row.previouslyAppliedActionId}
                </Badge>
              </TooltipTrigger>
              <TooltipContent>
                Corporate action #{row.previouslyAppliedActionId} already adjusted this
                record, so the Old values above are post-split. Ticking this row would
                split it a second time.
              </TooltipContent>
            </Tooltip>
          ) : null}
          {row.error ? (
            <span className="mt-1 text-destructive text-xs">{row.error}</span>
          ) : null}
        </div>
      </TableCell>
      <TableCell className="px-3 text-sm whitespace-nowrap">{row.tDate ?? "—"}</TableCell>

      <TableCell className="border-l px-3 text-right text-sm tabular-nums">
        {formatValue(row.old.quantity)}
      </TableCell>
      <TableCell className="px-3 text-right text-sm tabular-nums">
        {formatValue(row.old.price)}
      </TableCell>
      <TableCell className="px-3 text-right text-sm tabular-nums">
        {formatValue(row.old.tPrice)}
      </TableCell>
      <TableCell className="px-3 text-right text-sm tabular-nums">
        <AmountCell amount={row.old.amount} derived={row.old.derivedValue} />
      </TableCell>

      <TableCell className="border-l px-3 text-right font-medium text-sm tabular-nums">
        {formatValue(row.new.quantity)}
      </TableCell>
      <TableCell className="px-3 text-right font-medium text-sm tabular-nums">
        {formatValue(row.new.price)}
      </TableCell>
      <TableCell className="px-3 text-right font-medium text-sm tabular-nums">
        {formatValue(row.new.tPrice)}
      </TableCell>
      <TableCell className="px-3 text-right font-medium text-sm tabular-nums">
        <span className="inline-flex items-center gap-1.5">
          <AmountCell amount={row.new.amount} derived={row.new.derivedValue} />
          {row.hasAmountDrift ? (
            <Tooltip>
              <TooltipTrigger asChild>
                <AlertTriangle className="size-3.5 shrink-0 text-amber-600 dark:text-amber-500" />
              </TooltipTrigger>
              <TooltipContent>
                Amount changes by {formatValue(row.amountDrift)}. A split should leave
                it unchanged — check this row before applying.
              </TooltipContent>
            </Tooltip>
          ) : null}
        </span>
      </TableCell>
    </TableRow>
  );
}
