"use client"

import { errorMessageOr } from "@/lib/toast-api-error";

import * as React from "react"

import { useRenderEffect } from "@/hooks/use-changed";
import { ArrowLeft, Layers3, Loader2, X } from "lucide-react"

import { Button } from "@/components/ui/button"
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetTitle,
} from "@/components/ui/sheet"
import { cn } from "@/lib/utils"

import { EM_DASH, formatAccounting } from "@/lib/format/numbers"
import { ReportLifecycleBadge } from "@/app/customer/[tenant]/reports/_shared/components/report-lifecycle-badge"
import { fetchPibPivotDetailClient } from "../_lib/pib-pivot-detail-api"
import type {
  PibPivotDetailLine,
  PibPivotDetailLot,
  PibPivotDetailPayload,
} from "../_lib/pib-pivot-detail-types"
import type { PibPivotBucketKey } from "../_lib/pib-pivot-data"

/** Accounting-style value with an em dash for absent figures. */
function formatPibValue(value: number | null | undefined): string {
  return formatAccounting(value, EM_DASH)
}

export type PibPivotDetailTarget = {
  bucket: PibPivotBucketKey
  bucketLabel: string
  customerId: number
  bank: string
  client: string
  cellValue: number
}



function InfoChip({
  label,
  value,
  detail,
  mono,
}: {
  label: string
  value: string
  detail?: string
  mono?: boolean
}) {
  return (
    <div className="min-w-0 rounded-xl border border-border/60 bg-card/80 px-3 py-2 shadow-sm backdrop-blur-sm">
      <p className="text-[10px] font-medium uppercase tracking-wider text-muted-foreground">{label}</p>
      <p
        className={cn(
          "mt-0.5 truncate text-sm font-medium text-foreground",
          mono && "font-mono tracking-tight"
        )}
        title={value}
      >
        {value}
      </p>
      {detail ? (
        <p className="mt-0.5 truncate text-xs text-muted-foreground" title={detail}>
          {detail}
        </p>
      ) : null}
    </div>
  )
}

function UnmappedBadge() {
  return (
    <span className="inline-flex w-fit rounded-md bg-amber-100 px-1.5 py-0.5 text-[10px] font-medium text-amber-800 dark:bg-amber-950 dark:text-amber-300">
      Unmapped
    </span>
  )
}

function LabelCodeCell({
  label,
  code,
  unmapped,
  codeMono = true,
}: {
  label: string
  code: string
  unmapped?: boolean
  /** When false, secondary line is a plain name (e.g. asset class) not a short code. */
  codeMono?: boolean
}) {
  const name = label.trim()
  const shortCode = code.trim()

  if (!name && !shortCode) {
    return unmapped ? <UnmappedBadge /> : <span className="text-muted-foreground">—</span>
  }

  return (
    <div className="flex min-w-[8rem] flex-col gap-1 leading-tight">
      {unmapped ? <UnmappedBadge /> : null}
      {!name ? (
        <span
          className={cn(
            "text-[10px] text-muted-foreground",
            codeMono ? "font-mono" : "text-xs"
          )}
        >
          {shortCode}
        </span>
      ) : (
        <>
          <span className="text-xs">{name}</span>
          {shortCode ? (
            <span
              className={cn(
                "text-[10px] text-muted-foreground",
                codeMono ? "font-mono" : "text-xs"
              )}
            >
              {shortCode}
            </span>
          ) : null}
        </>
      )}
    </div>
  )
}

function lotsFor(line: PibPivotDetailLine): PibPivotDetailLot[] {
  return line.transactions?.length ? line.transactions : [line]
}

function HoldingsTable({
  detail,
  trackPibUnmapped = true,
  onIsinClick,
}: {
  detail: PibPivotDetailPayload
  trackPibUnmapped?: boolean
  onIsinClick: (line: PibPivotDetailLine) => void
}) {
  return (
    <div className="overflow-x-auto rounded-xl border border-border/60 bg-card shadow-sm">
      <table className="w-full min-w-[820px] border-collapse text-sm">
        <thead>
          <tr className="bg-sky-950 text-white">
            <th className="px-3 py-2.5 text-left text-[11px] font-semibold uppercase tracking-wide">
              ISIN
            </th>
            <th className="min-w-[18rem] px-3 py-2.5 text-left text-[11px] font-semibold uppercase tracking-wide">
              Name
            </th>
            <th className="min-w-[8rem] px-3 py-2.5 text-left text-[11px] font-semibold uppercase tracking-wide">
              Macro
            </th>
            <th className="min-w-[10rem] px-3 py-2.5 text-left text-[11px] font-semibold uppercase tracking-wide">
              Asset type
            </th>
            <th className="min-w-[12rem] px-3 py-2.5 text-left text-[11px] font-semibold uppercase tracking-wide">
              PIB class
            </th>
            <th className="px-3 py-2.5 text-right text-[11px] font-semibold uppercase tracking-wide">
              Value
            </th>
          </tr>
        </thead>
        <tbody>
          {detail.lines.map((line, index) => {
            const isPotential = Boolean(line.isPotential)
            const isUnmapped =
              !isPotential &&
              (!line.isAcMapped || (trackPibUnmapped && !line.isPibAssigned))
            const lotCount = lotsFor(line).length
            const isinTitle =
              lotCount > 1 ? `View ${lotCount} transactions` : "View transaction"
            const isinLabel = line.isin || "—"

            return (
            <tr
              key={`${line.isin}-${line.assetType}-${index}`}
              className={cn(
                "border-t border-border/60",
                index % 2 === 1 && "bg-muted/20",
                isUnmapped && "bg-amber-50/80 dark:bg-amber-950/20",
                isPotential && "bg-amber-500/5 dark:bg-amber-500/10"
              )}
            >
              <td className="px-3 py-2 font-mono text-xs">
                <button
                  type="button"
                  className="text-left underline-offset-2 hover:text-primary hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
                  title={isinTitle}
                  onClick={() => onIsinClick(line)}
                >
                  {isinLabel}
                </button>
              </td>
              <td className="max-w-[28rem] px-3 py-2" title={line.name || line.assetType}>
                <div className="flex flex-col gap-1">
                  {isPotential ? (
                    <ReportLifecycleBadge
                      kind="potential"
                      title="On Structured Products Potential tab — shown here but not included in PIB totals"
                      className="w-fit"
                    />
                  ) : null}
                  <span className="line-clamp-2">{line.name || line.assetType || "—"}</span>
                </div>
              </td>
              <td className="px-3 py-2 align-top">
                <LabelCodeCell
                  label={line.macro}
                  code={line.assetClassLabel || line.assetClass}
                  codeMono={false}
                  unmapped={!line.isAcMapped}
                />
              </td>
              <td className="max-w-[14rem] px-3 py-2 text-xs" title={line.assetType}>
                <span className="line-clamp-2">{line.assetType || "—"}</span>
              </td>
              <td className="px-3 py-2 align-top">
                <LabelCodeCell
                  label={line.pibClassLabel}
                  code={line.pibClass}
                  unmapped={trackPibUnmapped && !line.isPibAssigned}
                />
              </td>
              <td
                className={cn(
                  "px-3 py-2 text-right tabular-nums",
                  line.value < 0 && "text-red-600 dark:text-red-400"
                )}
              >
                {formatPibValue(line.value)}
              </td>
            </tr>
            )
          })}
        </tbody>
      </table>
    </div>
  )
}

function TransactionTable({
  line,
  reportingCurrency,
}: {
  line: PibPivotDetailLine
  reportingCurrency: string
}) {
  const lots = lotsFor(line)
  const totalValue = lots.reduce((sum, lot) => sum + (Number.isFinite(lot.value) ? lot.value : 0), 0)
  const totalQty = lots.reduce((sum, lot) => sum + (Number.isFinite(lot.quantity) ? lot.quantity : 0), 0)

  return (
    <div className="space-y-2">
      <p className="text-sm font-medium">
        {line.name || line.isin || "Transactions"}
        {line.isin ? (
          <span className="ml-2 font-mono text-xs font-normal text-muted-foreground">
            {line.isin}
          </span>
        ) : null}
      </p>
      <div className="overflow-x-auto rounded-xl border border-border/60 bg-card shadow-sm">
        <table className="w-full min-w-[880px] border-collapse text-sm">
          <thead>
            <tr className="bg-sky-950 text-white">
              <th className="px-3 py-2.5 text-left text-[11px] font-semibold uppercase tracking-wide">
                Ref ID
              </th>
              <th className="px-3 py-2.5 text-left text-[11px] font-semibold uppercase tracking-wide">
                Bank Name
              </th>
              <th className="px-3 py-2.5 text-left text-[11px] font-semibold uppercase tracking-wide">
                Trade Date
              </th>
              <th className="px-3 py-2.5 text-right text-[11px] font-semibold uppercase tracking-wide">
                Quantity
              </th>
              <th className="px-3 py-2.5 text-left text-[11px] font-semibold uppercase tracking-wide">
                Currency
              </th>
              <th className="px-3 py-2.5 text-right text-[11px] font-semibold uppercase tracking-wide">
                Price
              </th>
              <th className="px-3 py-2.5 text-right text-[11px] font-semibold uppercase tracking-wide">
                Purchase Value
              </th>
              <th className="px-3 py-2.5 text-right text-[11px] font-semibold uppercase tracking-wide">
                Market Value
              </th>
            </tr>
          </thead>
          <tbody>
            {lots.map((lot, index) => (
              <tr
                key={`${lot.refId}-${index}`}
                className={cn(
                  "border-t border-border/60",
                  index % 2 === 1 && "bg-muted/20"
                )}
              >
                <td className="px-3 py-2">{lot.refId || "—"}</td>
                <td className="px-3 py-2">{lot.bankName || "—"}</td>
                <td className="px-3 py-2">{lot.tradeDate || "—"}</td>
                <td className="px-3 py-2 text-right tabular-nums">
                  {formatPibValue(lot.quantity)}
                </td>
                <td className="px-3 py-2">{lot.currency || reportingCurrency}</td>
                <td className="px-3 py-2 text-right tabular-nums">
                  {formatPibValue(lot.price)}
                </td>
                <td className="px-3 py-2 text-right tabular-nums">
                  {formatPibValue(lot.purchaseValue)}
                </td>
                <td
                  className={cn(
                    "px-3 py-2 text-right tabular-nums",
                    lot.value < 0 && "text-red-600 dark:text-red-400"
                  )}
                >
                  {formatPibValue(lot.value)}
                </td>
              </tr>
            ))}
            <tr className="border-t border-border bg-muted/50 font-semibold">
              <td className="px-3 py-2.5 text-right" colSpan={3}>
                Total
              </td>
              <td className="px-3 py-2.5 text-right tabular-nums">
                {formatPibValue(totalQty)}
              </td>
              <td className="px-3 py-2.5" colSpan={3} />
              <td className="px-3 py-2.5 text-right tabular-nums">
                {formatPibValue(totalValue)}
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  )
}

export function PibPivotDetailDialog({
  target,
  asOfDate = "",
  open,
  onOpenChange,
}: {
  target: PibPivotDetailTarget | null
  asOfDate?: string
  open: boolean
  onOpenChange: (open: boolean) => void
}) {
  const [detail, setDetail] = React.useState<PibPivotDetailPayload | null>(null)
  const [selectedLine, setSelectedLine] = React.useState<PibPivotDetailLine | null>(null)
  const [loading, setLoading] = React.useState(false)
  const [errorMessage, setErrorMessage] = React.useState<string | null>(null)

  // Opening, closing or retargeting starts from a clean slate (adjusted during render, not in an effect).
  useRenderEffect([open, target, asOfDate], () => {
    setDetail(null)
    setErrorMessage(null)
    setSelectedLine(null)
    setLoading(Boolean(open && target))
  })

  React.useEffect(() => {
    if (!open || !target) return

    const controller = new AbortController()

    fetchPibPivotDetailClient(
      {
        bucket: target.bucket,
        customerId: target.customerId,
        bank: target.bank,
        asOfDate: asOfDate.trim() || undefined,
      },
      controller.signal
    )
      .then((payload) => {
        setDetail(payload)
      })
      .catch((error: unknown) => {
        if (controller.signal.aborted) return
        setErrorMessage(errorMessageOr(error, "Could not load holdings."))
      })
      .finally(() => {
        if (!controller.signal.aborted) {
          setLoading(false)
        }
      })

    return () => controller.abort()
  }, [open, target, asOfDate])

  const currency = detail?.defaultCurrencyCode ?? "USD"
  const trackPibUnmapped = target?.bucket !== "moneyMarket"

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent
        side="right"
        showCloseButton={false}
        className={cn(
          "flex h-dvh w-full flex-col gap-0 overflow-hidden bg-muted/30 p-0",
          "data-[side=right]:w-full data-[side=right]:sm:max-w-none",
          "data-[side=right]:sm:!w-[min(72rem,calc(100vw-1.5rem))]"
        )}
      >
        <div className="shrink-0 space-y-2 border-b border-border/60 bg-card/80 px-4 pt-4 pb-3 backdrop-blur-md">
          <p className="text-[10px] font-semibold uppercase tracking-widest text-muted-foreground">
            {selectedLine ? "Transactions" : "Holdings"}
          </p>
          <div className="flex items-center justify-between gap-2">
            <SheetTitle className="flex min-w-0 items-center gap-2 text-left text-base font-semibold tracking-tight">
              {selectedLine ? (
                <Button
                  type="button"
                  variant="ghost"
                  size="icon-sm"
                  className="rounded-lg"
                  onClick={() => setSelectedLine(null)}
                  aria-label="Back to holdings"
                >
                  <ArrowLeft className="size-4" />
                </Button>
              ) : (
                <span className="flex size-8 shrink-0 items-center justify-center rounded-xl bg-primary text-primary-foreground shadow-md shadow-primary/25">
                  <Layers3 className="size-3.5" />
                </span>
              )}
              <span className="truncate">
                {selectedLine
                  ? selectedLine.name || selectedLine.isin || "Transactions"
                  : (target?.bucketLabel ?? "PIB bucket holdings")}
              </span>
            </SheetTitle>
            <Button
              type="button"
              variant="ghost"
              size="icon-sm"
              className="rounded-lg"
              onClick={() => onOpenChange(false)}
              aria-label="Close"
            >
              <X className="size-4" />
            </Button>
          </div>
          <SheetDescription className="sr-only">
            Clubbed holdings for this PIB pivot cell, with lot-level transactions on amount click.
          </SheetDescription>
        </div>

        <div className="flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto px-4 py-4">
          {target ? (
            <section className="flex flex-col gap-3 rounded-2xl border border-border/60 bg-card p-3 shadow-sm">
              <div className="grid gap-2 sm:grid-cols-3">
                <InfoChip label="Customer" value={target.client || "—"} />
                <InfoChip label="Bank" value={target.bank || "—"} />
                <InfoChip label="PIB bucket" value={target.bucketLabel || "—"} />
              </div>
              {detail ? (
                <>
                  <div className="grid gap-2 sm:grid-cols-3">
                    <InfoChip label="Holdings" value={String(detail.lineCount)} />
                    <InfoChip
                      label={`Bucket total (${currency})`}
                      value={formatPibValue(detail.totalValue)}
                    />
                    <InfoChip label="Pivot cell" value={formatPibValue(target.cellValue)} />
                  </div>
                  {trackPibUnmapped ? (
                    <div className="grid gap-2 sm:grid-cols-3">
                      <InfoChip
                        label={`Assigned (${currency})`}
                        value={formatPibValue(detail.assignedValue)}
                        detail="OS / ISIN master PIB"
                      />
                      <InfoChip
                        label={`Inferred (${currency})`}
                        value={formatPibValue(detail.inferredValue)}
                        detail={
                          detail.unmappedPibCount > 0
                            ? `${detail.unmappedPibCount} holding${detail.unmappedPibCount === 1 ? "" : "s"} · AC rules only`
                            : "None in this cell"
                        }
                      />
                      {detail.unmappedAcCount > 0 ? (
                        <InfoChip
                          label="Unmapped Macro"
                          value={String(detail.unmappedAcCount)}
                          detail="No Macro Asset Class for holding"
                        />
                      ) : (
                        <div className="hidden sm:block" />
                      )}
                    </div>
                  ) : detail.unmappedAcCount > 0 ? (
                    <InfoChip
                      label="Unmapped Macro"
                      value={String(detail.unmappedAcCount)}
                      detail="No Macro Asset Class for holding"
                    />
                  ) : null}
                  {detail.potentialCount > 0 ? (
                    <InfoChip
                      label={`Potential (${currency})`}
                      value={formatPibValue(detail.potentialValue)}
                      detail={`${detail.potentialCount} note${detail.potentialCount === 1 ? "" : "s"} · shown, not in PIB totals`}
                    />
                  ) : null}
                </>
              ) : null}
            </section>
          ) : null}

          {loading ? (
            <div className="flex items-center gap-2 py-10 text-sm text-muted-foreground">
              <Loader2 className="size-4 animate-spin" />
              Loading…
            </div>
          ) : null}

          {errorMessage ? <p className="text-destructive text-sm">{errorMessage}</p> : null}

          {!loading && !errorMessage && detail ? (
            detail.lines.length === 0 ? (
              <p className="text-muted-foreground text-sm">No holdings in this bucket.</p>
            ) : selectedLine ? (
              <TransactionTable line={selectedLine} reportingCurrency={currency} />
            ) : (
              <HoldingsTable
                detail={detail}
                trackPibUnmapped={trackPibUnmapped}
                onIsinClick={setSelectedLine}
              />
            )
          ) : null}
        </div>
      </SheetContent>
    </Sheet>
  )
}
