"use client"

import Link from "next/link"
import { useMemo, useState } from "react"
import { ChevronDown, GitCompareArrows } from "lucide-react"

import { ListPageCard } from "@/app/dashboard/_components"
import { XmlApiErrorBanner } from "@/components/xml-apis/shared/xml-api-error-banner"
import type {
  IdLabelMap,
  PosReconV2CustomerGroup,
  PosReconV2Line,
  PosReconV2Run,
} from "@/components/xml-apis/pos-recon-v2/types"
import { PosReconV2StatCards } from "@/components/xml-apis/pos-recon-v2/components/pos-recon-v2-stat-cards"

type Props = {
  runId: number
  initialRun: PosReconV2Run | null
  initialGroups: PosReconV2CustomerGroup[]
  initialCounts: Record<string, number>
  statusLabels: IdLabelMap
  initialStatus: string
  corporateId: number
  initialErrorMessage?: string | null
}

const STATUS_COLORS: Record<string, string> = {
  matched: "#1e7e34",
  mismatch: "#c47b00",
  missing_in_xml: "#0d6efd",
  missing_in_oxy: "#6f42c1",
  unmapped_customer: "#b02a37",
}

function statusCountForGroup(group: PosReconV2CustomerGroup, status: string): number {
  if (!status) return group.row_count
  if (status === "matched") return group.matched_count
  if (status === "mismatch") return group.mismatch_count
  if (status === "missing_in_oxy") return group.missing_oxy_count
  if (status === "missing_in_xml") return group.missing_xml_count
  if (status === "unmapped_customer") return group.unmapped_count
  return group.rows.filter((row) => row.match_status === status).length
}

function formatQty(value: number | string | null | undefined): string {
  if (value == null || value === "") return ""
  const num = Number(value)
  if (!Number.isFinite(num)) return String(value)
  return Number.isInteger(num) ? String(num) : num.toLocaleString(undefined, { maximumFractionDigits: 6 })
}

function LineTable({
  rows,
  statusLabels,
}: {
  rows: PosReconV2Line[]
  statusLabels: IdLabelMap
}) {
  if (rows.length === 0) {
    return (
      <div className="px-4 py-6 text-center text-sm text-muted-foreground">
        No lines for this filter.
      </div>
    )
  }

  return (
    <div className="overflow-x-auto">
      <table className="min-w-full text-sm">
        <thead className="bg-muted/40 text-left">
          <tr>
            <th className="px-3 py-2 font-medium">Status</th>
            <th className="px-3 py-2 font-medium">Account</th>
            <th className="px-3 py-2 font-medium">XML ISIN</th>
            <th className="px-3 py-2 font-medium">Oxy ISIN</th>
            <th className="px-3 py-2 font-medium">AC</th>
            <th className="px-3 py-2 text-right font-medium">XML qty</th>
            <th className="px-3 py-2 text-right font-medium">OS qty</th>
            <th className="px-3 py-2 text-right font-medium">Delta</th>
            <th className="px-3 py-2 font-medium">Reason</th>
          </tr>
        </thead>
        <tbody>
          {rows.map((line, index) => {
            const color = STATUS_COLORS[line.match_status] || "#555"
            const label = statusLabels[line.match_status] || line.match_status
            return (
              <tr key={line.row_key || `${line.identity_key}-${index}`} className="border-t">
                <td className="px-3 py-2 whitespace-nowrap">
                  <span
                    className="inline-flex rounded-full px-2 py-0.5 text-xs font-medium"
                    style={{ color, backgroundColor: `${color}14` }}
                  >
                    {label}
                  </span>
                </td>
                <td className="px-3 py-2 whitespace-nowrap">{line.account_number ?? ""}</td>
                <td className="px-3 py-2 font-mono text-xs">{line.xml_isin}</td>
                <td className="px-3 py-2 font-mono text-xs">{line.oxy_isin}</td>
                <td className="px-3 py-2">{line.asset_class}</td>
                <td className="px-3 py-2 text-right tabular-nums">{formatQty(line.xml_qty)}</td>
                <td className="px-3 py-2 text-right tabular-nums">{formatQty(line.os_qty)}</td>
                <td className="px-3 py-2 text-right tabular-nums">{formatQty(line.delta)}</td>
                <td className="px-3 py-2 text-muted-foreground">
                  {line.leftover_reason_label || line.tag_error || ""}
                </td>
              </tr>
            )
          })}
        </tbody>
      </table>
    </div>
  )
}

function CustomerGroupPanel({
  group,
  statusFilter,
  statusLabels,
  defaultOpen,
}: {
  group: PosReconV2CustomerGroup
  statusFilter: string
  statusLabels: IdLabelMap
  defaultOpen: boolean
}) {
  const [open, setOpen] = useState(defaultOpen)
  const filteredRows = useMemo(
    () =>
      statusFilter
        ? group.rows.filter((row) => row.match_status === statusFilter)
        : group.rows,
    [group.rows, statusFilter]
  )

  const badges = [
    { key: "all", label: "All", count: group.row_count },
    { key: "matched", label: "matched", count: group.matched_count },
    { key: "mismatch", label: "mismatch", count: group.mismatch_count },
    { key: "missing_in_oxy", label: "missing Oxy", count: group.missing_oxy_count },
    { key: "missing_in_xml", label: "missing XML", count: group.missing_xml_count },
    ...(group.unmapped_count > 0
      ? [{ key: "unmapped_customer", label: "unmapped", count: group.unmapped_count }]
      : []),
  ]

  return (
    <div className="overflow-hidden rounded-md border">
      <button
        type="button"
        onClick={() => setOpen((value) => !value)}
        className="flex w-full items-start justify-between gap-3 bg-muted/30 px-4 py-3 text-left hover:bg-muted/50"
      >
        <div className="min-w-0">
          <div className="flex items-center gap-2 font-medium">
            <ChevronDown
              className={`h-4 w-4 shrink-0 transition-transform ${open ? "" : "-rotate-90"}`}
            />
            <span className="truncate">{group.label}</span>
          </div>
          {group.ac_counts.length > 0 ? (
            <div className="mt-2 flex flex-wrap gap-1.5 pl-6">
              {group.ac_counts.map((ac) => (
                <span
                  key={ac.slug}
                  className="rounded-full border bg-background px-2 py-0.5 text-xs text-muted-foreground"
                >
                  {ac.label} <b className="text-foreground">{ac.count}</b>
                </span>
              ))}
            </div>
          ) : null}
        </div>
        <div className="flex max-w-[55%] flex-wrap justify-end gap-1.5">
          {badges.map((badge) => (
            <span
              key={badge.key}
              className={`rounded-full border px-2 py-0.5 text-xs ${
                badge.count > 0 ? "border-border bg-background" : "border-transparent text-muted-foreground"
              }`}
            >
              {badge.count} {badge.label}
            </span>
          ))}
        </div>
      </button>
      {open ? (
        <div className="border-t">
          <div className="flex items-center justify-between gap-2 border-b px-4 py-2 text-xs text-muted-foreground">
            <span>
              Showing {filteredRows.length} / {group.row_count}
              {statusFilter ? ` · ${statusLabels[statusFilter] || statusFilter}` : ""}
            </span>
          </div>
          <LineTable rows={filteredRows} statusLabels={statusLabels} />
        </div>
      ) : null}
    </div>
  )
}

export function PosReconV2DetailPage({
  runId,
  initialRun,
  initialGroups,
  initialCounts,
  statusLabels,
  initialStatus,
  corporateId,
  initialErrorMessage = null,
}: Props) {
  const [statusFilter, setStatusFilter] = useState(initialStatus)

  const visibleGroups = useMemo(() => {
    return initialGroups
      .map((group) => ({
        group,
        visibleCount: statusCountForGroup(group, statusFilter),
      }))
      .filter((item) => item.visibleCount > 0)
  }, [initialGroups, statusFilter])

  function onSelectStatus(status: string) {
    setStatusFilter(status)
    const params = new URLSearchParams()
    if (status) params.set("status", status)
    if (corporateId) params.set("corporate_id", String(corporateId))
    const query = params.toString()
    window.history.replaceState(
      null,
      "",
      `/dashboard/xml-apis/pos-recon-v2/${runId}${query ? `?${query}` : ""}`
    )
  }

  const backHref = corporateId
    ? `/dashboard/xml-apis/pos-recon-v2?corporate_id=${corporateId}`
    : "/dashboard/xml-apis/pos-recon-v2"

  return (
    <ListPageCard
      icon={GitCompareArrows}
      title={`POS Recon v2 · Run #${runId}`}
      description={
        initialRun
          ? `Upload #${initialRun.upload_id ?? "—"} · as-of ${initialRun.as_of_date ?? "—"} · ${initialRun.status ?? ""}`
          : "Run detail"
      }
      breadcrumb={[
        { label: "XML API" },
        { label: "POS Recon v2", href: backHref },
        { label: `Run #${runId}` },
      ]}
      actions={
        <Link href={backHref} className="text-sm text-muted-foreground hover:text-foreground">
          Back to runs
        </Link>
      }
    >
      <XmlApiErrorBanner message={initialErrorMessage} />
      <PosReconV2StatCards
        counts={initialCounts}
        activeStatus={statusFilter}
        onSelectStatus={onSelectStatus}
        totalXml={initialCounts.xml_rows}
        totalOs={initialCounts.os_rows}
      />
      <div className="mt-4 flex flex-wrap items-center justify-between gap-2 text-sm text-muted-foreground">
        <span>
          Customers: <b className="text-foreground">{visibleGroups.length}</b>
          {" / "}
          {initialGroups.length}
          {statusFilter ? (
            <>
              {" · filter "}
              <b className="text-foreground">{statusLabels[statusFilter] || statusFilter}</b>
            </>
          ) : null}
        </span>
        {statusFilter ? (
          <button
            type="button"
            className="text-sm underline-offset-2 hover:underline"
            onClick={() => onSelectStatus("")}
          >
            Clear status filter
          </button>
        ) : null}
      </div>
      <div className="mt-3 space-y-3">
        {visibleGroups.length === 0 ? (
          <div className="rounded-md border px-4 py-8 text-center text-sm text-muted-foreground">
            No customers have rows for this filter.
          </div>
        ) : (
          visibleGroups.map(({ group }, index) => (
            <CustomerGroupPanel
              key={group.key}
              group={group}
              statusFilter={statusFilter}
              statusLabels={statusLabels}
              defaultOpen={index === 0}
            />
          ))
        )}
      </div>
    </ListPageCard>
  )
}
