"use client"

import * as React from "react"
import { 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 { formatAccounting } from "@/lib/format/numbers"
import { fetchPibPivotDetailClient } from "../_lib/pib-pivot-detail-api"
import type { PibPivotDetailPayload } from "../_lib/pib-pivot-detail-types"
import type { PibPivotBucketKey } from "../_lib/pib-pivot-data"

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

function formatMoney(value: number | null | undefined): string {
  return formatAccounting(value, "—")
}

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,
}: {
  label: string
  code: string
  unmapped?: 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="font-mono text-[10px] text-muted-foreground">{shortCode}</span>
      ) : (
        <>
          <span className="text-xs">{name}</span>
          {shortCode ? (
            <span className="font-mono text-[10px] text-muted-foreground">{shortCode}</span>
          ) : null}
        </>
      )}
    </div>
  )
}

function HoldingsTable({
  detail,
  trackPibUnmapped = true,
}: {
  detail: PibPivotDetailPayload
  trackPibUnmapped?: boolean
}) {
  return (
    <div className="overflow-x-auto rounded-xl border border-border/60 bg-card shadow-sm">
      <table className="w-full min-w-[900px] border-collapse text-sm">
        <thead>
          <tr className="bg-sky-950 text-primary-foreground">
            <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">
              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">
              Mapped AC
            </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 isUnmapped =
              !line.isAcMapped || (trackPibUnmapped && !line.isPibAssigned)

            return (
            <tr
              key={`${line.refId}-${line.isin}-${index}`}
              className={cn(
                "border-t border-border/60",
                index % 2 === 1 && "bg-muted/20",
                isUnmapped && "bg-amber-50/80 dark:bg-amber-950/20"
              )}
            >
              <td className="px-3 py-2 font-mono text-xs">{line.refId || "—"}</td>
              <td className="px-3 py-2 font-mono text-xs">{line.isin || "—"}</td>
              <td className="max-w-[28rem] px-3 py-2" title={line.name || line.assetType}>
                <span className="line-clamp-2">{line.name || line.assetType || "—"}</span>
              </td>
              <td className="px-3 py-2 align-top">
                <LabelCodeCell
                  label={line.mappedAc}
                  code={line.assetClass}
                  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"
                )}
              >
                {formatMoney(line.value)}
              </td>
            </tr>
            )
          })}
        </tbody>
      </table>
    </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 [loading, setLoading] = React.useState(false)
  const [errorMessage, setErrorMessage] = React.useState<string | null>(null)

  React.useEffect(() => {
    if (!open || !target) {
      setDetail(null)
      setErrorMessage(null)
      return
    }

    const controller = new AbortController()
    setLoading(true)
    setErrorMessage(null)
    setDetail(null)

    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(error instanceof Error ? error.message : "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">
            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">
              <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">{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">
            Overall Summary line items for this PIB pivot cell.
          </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="Lines" value={String(detail.lineCount)} />
                    <InfoChip
                      label={`Bucket total (${currency})`}
                      value={formatMoney(detail.totalValue)}
                    />
                    <InfoChip label="Pivot cell" value={formatMoney(target.cellValue)} />
                  </div>
                  {trackPibUnmapped ? (
                    <div className="grid gap-2 sm:grid-cols-3">
                      <InfoChip
                        label={`Assigned (${currency})`}
                        value={formatMoney(detail.assignedValue)}
                        detail="OS / ISIN master PIB"
                      />
                      <InfoChip
                        label={`Inferred (${currency})`}
                        value={formatMoney(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 AC"
                          value={String(detail.unmappedAcCount)}
                          detail="No mapped asset class on holding"
                        />
                      ) : (
                        <div className="hidden sm:block" />
                      )}
                    </div>
                  ) : detail.unmappedAcCount > 0 ? (
                    <InfoChip
                      label="Unmapped AC"
                      value={String(detail.unmappedAcCount)}
                      detail="No mapped asset class on holding"
                    />
                  ) : 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>
            ) : (
              <HoldingsTable detail={detail} trackPibUnmapped={trackPibUnmapped} />
            )
          ) : null}
        </div>
      </SheetContent>
    </Sheet>
  )
}
