"use client";

import type { ColumnDef } from "@tanstack/react-table";
import { resolveCustomerTenant } from "@/app/customer/_lib/resolve-customer-tenant";
import { ClipboardPlus, Eye, FileText, ScrollText } from "lucide-react";
import Link from "next/link";
import { toast } from "sonner";

import type { CustomerGridColumn } from "@/app/customer/_lib/customer-grid-columns";
import type { StandardAssetCreateColumnsOptions } from "@/app/customer/_components/customer-standard-asset-list-table";
import { CustomerSortableHeader } from "@/components/customer/customer-table-primitives";
import { Button } from "@/components/ui/button";
import { formatApiDate } from "@/lib/format/dates";
import { formatAmount } from "@/lib/format/numbers";
import { customerUrl } from "@/lib/tenant";
import { buildOrderBlotterCreateQuery } from "@/lib/order-blotter/route-params";
import { cn } from "@/lib/utils";

import type { TransactionRow } from "./schema";

export const TRANSACTIONS_OPTIONS_COLUMN_ID = "options";

export const FALLBACK_TRANSACTIONS_GRID_COLUMNS: CustomerGridColumn[] = [
  { key: "uid_title", label: "Ref. ID", defaultVisible: true },
  { key: "primary_rm", label: "Primary RM", defaultVisible: true },
  { key: "name", label: "Name", defaultVisible: true },
  { key: "placement_date", label: "Placement Date", defaultVisible: true },
  { key: "bank", label: "Bank", defaultVisible: true },
  { key: "security_ticker", label: "Security Ticker", defaultVisible: true },
  { key: "category", label: "Category", defaultVisible: true },
  { key: "price_formatted", label: "Price", defaultVisible: true },
  { key: "quantity_formatted", label: "Quantity", defaultVisible: true },
  { key: "currency", label: "Currency", defaultVisible: true },
  { key: "amount_formatted", label: "Amount", defaultVisible: true },
];

const FALLBACK_COLUMNS = FALLBACK_TRANSACTIONS_GRID_COLUMNS;

function valueForKey(row: TransactionRow, key: string): string {
  return row.valuesByKey[key] ?? "";
}

function textCell(value: string, className?: string) {
  return <span className={cn("text-sm", className)}>{value.trim() ? value : "—"}</span>;
}

function orderBlotterHref(row: TransactionRow, tenant: string): string | null {
  const ob = row.orderBlotter;
  if (!ob?.action) return null;
  if (ob.action === "view" && (ob.blotterId || ob.ref)) {
    const id = ob.blotterId ?? 0;
    const params = new URLSearchParams({ action: "view" });
    if (ob.ref) params.set("ref", ob.ref);
    return customerUrl(tenant, `/order-blotter/${id}?${params.toString()}`);
  }
  if (ob.action === "create" && ob.transactionId) {
    const qs = buildOrderBlotterCreateQuery({
      transactionId: ob.transactionId,
      customerId: ob.customerId,
      corporateDb: ob.corporateDb,
    });
    return customerUrl(tenant, `/order-blotter/create?${qs}`);
  }
  return null;
}

function createColumnDef(
  column: CustomerGridColumn,
): ColumnDef<TransactionRow> {
  const label = column.label;

  switch (column.key) {
    case "uid_title":
      return {
        id: column.key,
        accessorFn: (row) => row.refId,
        header: ({ column: tableColumn }) => (
          <CustomerSortableHeader label={label} column={tableColumn} />
        ),
        cell: ({ row }) => textCell(row.original.refId, "whitespace-nowrap"),
      };
    case "primary_rm":
      return {
        id: column.key,
        accessorFn: (row) => row.primaryRm,
        header: ({ column: tableColumn }) => (
          <CustomerSortableHeader label={label} column={tableColumn} />
        ),
        cell: ({ row }) => textCell(row.original.primaryRm),
      };
    case "name":
      return {
        id: column.key,
        accessorFn: (row) => row.accountName,
        header: ({ column: tableColumn }) => (
          <CustomerSortableHeader label={label} column={tableColumn} />
        ),
        cell: ({ row }) => textCell(row.original.accountName, "min-w-40"),
      };
    case "placement_date":
      return {
        id: column.key,
        accessorFn: (row) => row.placementDate,
        header: ({ column: tableColumn }) => (
          <CustomerSortableHeader label={label} column={tableColumn} />
        ),
        cell: ({ row }) => (
          <span className="whitespace-nowrap text-sm">
            {formatApiDate(row.original.placementDate, "dd MMM yyyy", row.original.placementDate) ||
              "—"}
          </span>
        ),
      };
    case "bank":
      return {
        id: column.key,
        accessorFn: (row) => row.bank,
        header: ({ column: tableColumn }) => (
          <CustomerSortableHeader label={label} column={tableColumn} />
        ),
        cell: ({ row }) => textCell(row.original.bank),
      };
    case "security_ticker":
      return {
        id: column.key,
        accessorFn: (row) => row.securityTicker,
        header: ({ column: tableColumn }) => (
          <CustomerSortableHeader label={label} column={tableColumn} />
        ),
        cell: ({ row }) => textCell(row.original.securityTicker, "whitespace-nowrap font-mono text-xs"),
      };
    case "category":
      return {
        id: column.key,
        accessorFn: (row) => row.category,
        header: ({ column: tableColumn }) => (
          <CustomerSortableHeader label={label} column={tableColumn} />
        ),
        cell: ({ row }) => textCell(row.original.category, "whitespace-nowrap"),
      };
    case "price_formatted":
      return {
        id: column.key,
        accessorFn: (row) => row.price,
        header: ({ column: tableColumn }) => (
          <CustomerSortableHeader label={label} column={tableColumn} />
        ),
        cell: ({ row }) => (
          <span className="block text-right text-sm tabular-nums">
            {row.original.price > 0 ? row.original.price.toFixed(2) : "—"}
          </span>
        ),
      };
    case "quantity_formatted":
      return {
        id: column.key,
        accessorFn: (row) => row.quantity,
        header: ({ column: tableColumn }) => (
          <CustomerSortableHeader label={label} column={tableColumn} />
        ),
        cell: ({ row }) => (
          <span className="block text-right text-sm tabular-nums">
            {row.original.quantity.toFixed(2)}
          </span>
        ),
      };
    case "currency":
      return {
        id: column.key,
        accessorFn: (row) => row.currency,
        header: ({ column: tableColumn }) => (
          <CustomerSortableHeader label={label} column={tableColumn} />
        ),
        cell: ({ row }) => textCell(row.original.currency),
      };
    case "amount_formatted":
      return {
        id: column.key,
        accessorFn: (row) => row.amount,
        header: ({ column: tableColumn }) => (
          <CustomerSortableHeader label={label} column={tableColumn} />
        ),
        cell: ({ row }) => (
          <span
            className={cn(
              "block text-right font-medium text-sm tabular-nums",
              row.original.amount < 0
                ? "text-red-600 dark:text-red-400"
                : row.original.amount > 0
                  ? "text-green-600 dark:text-green-400"
                  : "",
            )}
          >
            {formatAmount(row.original.amount)}
          </span>
        ),
      };
    default:
      return {
        id: column.key,
        accessorFn: (row) => valueForKey(row, column.key),
        header: ({ column: tableColumn }) => (
          <CustomerSortableHeader label={label} column={tableColumn} />
        ),
        cell: ({ row }) => textCell(valueForKey(row.original, column.key), "whitespace-nowrap"),
      };
  }
}

function createOptionsColumn(
  onView: (row: TransactionRow) => void,
  tenant: string,
): ColumnDef<TransactionRow> {
  return {
    id: TRANSACTIONS_OPTIONS_COLUMN_ID,
    header: () => <span className="font-medium text-sm">Options</span>,
    size: 108,
    minSize: 108,
    maxSize: 108,
    cell: ({ row }) => {
      const blotterHref = orderBlotterHref(row.original, tenant);
      const blotterAction = row.original.orderBlotter?.action;
      const blotterTitle =
        row.original.orderBlotter?.title ||
        (blotterAction === "view" ? "View order blotter" : "Create order blotter");

      return (
        <div className="flex items-center justify-end gap-0.5 whitespace-nowrap">
          <Button
            variant="ghost"
            size="icon-sm"
            className="text-sky-600 hover:bg-sky-500/10 hover:text-sky-700 dark:text-sky-400"
            onClick={() => onView(row.original)}
          >
            <Eye className="size-4" />
            <span className="sr-only">View transaction details for {row.original.securityName}</span>
          </Button>
          <Button
            variant="ghost"
            size="icon-sm"
            className="text-emerald-600 hover:bg-emerald-500/10 hover:text-emerald-700 dark:text-emerald-400"
            onClick={() =>
              toast.info("View document", {
                description: `${row.original.securityName} (${row.original.refId}) — document viewer coming soon.`,
              })
            }
          >
            <FileText className="size-4" />
            <span className="sr-only">View document for {row.original.securityName}</span>
          </Button>
          {blotterHref ? (
            <Button
              variant="ghost"
              size="icon-sm"
              className="text-violet-600 hover:bg-violet-500/10 hover:text-violet-700 dark:text-violet-400"
              asChild
            >
              <Link href={blotterHref} title={blotterTitle}>
                {blotterAction === "view" ? (
                  <ScrollText className="size-4" />
                ) : (
                  <ClipboardPlus className="size-4" />
                )}
                <span className="sr-only">{blotterTitle}</span>
              </Link>
            </Button>
          ) : null}
        </div>
      );
    },
    enableSorting: false,
    enableHiding: false,
  };
}

export function createAllTransactionsColumns(
  gridColumns: CustomerGridColumn[],
  onView: (row: TransactionRow) => void,
  _onEdit: (row: TransactionRow) => void,
  _options: StandardAssetCreateColumnsOptions,
): ColumnDef<TransactionRow>[] {
  const catalog = gridColumns?.length ? gridColumns : FALLBACK_COLUMNS;
  const resolvedTenant = resolveCustomerTenant();
  return [...catalog.map(createColumnDef), createOptionsColumn(onView, resolvedTenant)];
}
