import Link from "next/link"
import { notFound } from "next/navigation"
import { Percent } from "lucide-react"

import { ListPageCard } from "@/app/dashboard/_components"
import { ErrorBanner } from "@/components/shared/error-banner"
import { BACKEND_ENDPOINTS } from "@/config/backend-endpoints"
import { fetchAuthenticatedBackendJson } from "@/lib/backend-client"
import { isRecord, stringOrEmpty } from "@/lib/server-utils"

import { IsinAssetMasterDetailActions } from "../_components/isin-asset-master-detail-actions"
import { IsinAssetMasterPibSelect } from "../_components/isin-asset-master-pib-select"
import { normalizePibClassList } from "../_lib/pib-class-options"
import { LIST_HREF } from "../_components/schema"

type PageProps = { params: Promise<{ id: string }> }

export default async function IsinAssetMasterDetailPage({ params }: PageProps) {
  const { id } = await params
  const result = await fetchDetail(id)
  if (result.notFound) notFound()

  const model = result.model
  const probabilities = result.probabilities
  const pibClassList = result.pibClassList
  const isinNames = Array.from(
    new Set(
      probabilities.rows
        .map((row) => row.isin_name.trim())
        .filter((name) => name !== "")
    )
  )
  if (isinNames.length === 0 && model.isinName) {
    isinNames.push(model.isinName)
  }

  return (
    <ListPageCard
      icon={Percent}
      title={
        model.isin
          ? `${model.isin}${model.isinName ? ` · ${model.isinName}` : ""} · ${probabilities.bank_count} bank${probabilities.bank_count === 1 ? "" : "s"}`
          : id
      }
      description={`${probabilities.bank_count} bank vote${probabilities.bank_count === 1 ? "" : "s"}; computed probabilities, lock / edit.`}
      breadcrumb={[
        { label: "Master Table" },
        { label: "ISIN Asset Master", href: LIST_HREF },
        { label: model.isin || id },
      ]}
      actions={<IsinAssetMasterDetailActions id={model.id} status={model.status} />}
    >
      <ErrorBanner message={result.errorMessage} className="mb-4" />
      <div className="mb-4">
        <Link href={LIST_HREF} className="text-sm text-sky-700 hover:underline">
          Back to list
        </Link>
      </div>
      <dl className="mb-6 grid gap-3 rounded-lg border bg-card p-4 sm:grid-cols-2">
        <div>
          <dt className="text-xs text-muted-foreground">ISIN Name{isinNames.length > 1 ? "s" : ""}</dt>
          <dd className="text-sm font-medium">
            {isinNames.length === 0 ? (
              "—"
            ) : (
              <ul className="space-y-0.5">
                {isinNames.map((name) => (
                  <li key={name}>{name}</li>
                ))}
              </ul>
            )}
          </dd>
        </div>
        <div>
          <dt className="text-xs text-muted-foreground">Asset Class</dt>
          <dd className="text-sm font-medium">
            {model.aClassLabel} ({model.aClass})
          </dd>
        </div>
        <div>
          <dt className="text-xs text-muted-foreground">Asset Type</dt>
          <dd className="text-sm font-medium">{model.aType || "—"}</dd>
        </div>
        <div>
          <dt className="mb-1 text-xs text-muted-foreground">PIB</dt>
          <dd>
            <IsinAssetMasterPibSelect
              id={model.id}
              value={model.pibClass}
              options={pibClassList}
            />
          </dd>
        </div>
        <div>
          <dt className="text-xs text-muted-foreground">Status</dt>
          <dd className="text-sm font-medium">{model.statusLabel}</dd>
        </div>
        <div>
          <dt className="text-xs text-muted-foreground">Confidence %</dt>
          <dd className="text-sm font-medium">
            {model.confidenceAc == null ? "—" : model.confidenceAc}
          </dd>
        </div>
        <div>
          <dt className="text-xs text-muted-foreground">Updated</dt>
          <dd className="text-sm font-medium">{model.updatedAt || "—"}</dd>
        </div>
      </dl>

      <h3 className="mb-2 text-sm font-semibold">AC probabilities</h3>
      <ul className="mb-6 space-y-1 rounded-lg border bg-card p-4 text-sm">
        {Object.keys(probabilities.ac).length === 0 ? (
          <li className="text-muted-foreground">No bank votes yet.</li>
        ) : (
          Object.entries(probabilities.ac).map(([code, pct]) => (
            <li key={code} className="flex justify-between font-mono">
              <span>{code}</span>
              <span>{pct}%</span>
            </li>
          ))
        )}
      </ul>

      <h3 className="mb-2 text-sm font-semibold">
        Bank votes ({probabilities.bank_count})
      </h3>
      <div className="overflow-x-auto rounded-lg border bg-card">
        <table className="w-full text-left text-sm">
          <thead className="border-b bg-muted/40 text-xs text-muted-foreground">
            <tr>
              <th className="px-3 py-2">Bank</th>
              <th className="px-3 py-2">ISIN Name</th>
              <th className="px-3 py-2">Category</th>
              <th className="px-3 py-2">AC</th>
              <th className="px-3 py-2">AT</th>
              <th className="px-3 py-2">Source</th>
              <th className="px-3 py-2">Updated</th>
            </tr>
          </thead>
          <tbody>
            {probabilities.rows.length === 0 ? (
              <tr>
                <td colSpan={7} className="px-3 py-6 text-center text-muted-foreground">
                  No assignment rows.
                </td>
              </tr>
            ) : (
              probabilities.rows.map((row) => (
                <tr key={`${row.isin}-${row.bank_api_id}`} className="border-b last:border-0">
                  <td className="px-3 py-2">
                    <div className="font-medium">{row.bank_name || `Bank #${row.bank_api_id}`}</div>
                    <div className="font-mono text-xs text-muted-foreground">
                      ID {row.bank_api_id}
                    </div>
                  </td>
                  <td className="px-3 py-2">{row.isin_name || "—"}</td>
                  <td className="px-3 py-2">{row.api_category}</td>
                  <td className="px-3 py-2 font-mono">{row.a_class}</td>
                  <td className="px-3 py-2">{row.a_type || "—"}</td>
                  <td className="px-3 py-2">{row.source}</td>
                  <td className="px-3 py-2 text-xs">{row.updated_at}</td>
                </tr>
              ))
            )}
          </tbody>
        </table>
      </div>
    </ListPageCard>
  )
}

async function fetchDetail(id: string) {
  const { response, status, errorMessage } = await fetchAuthenticatedBackendJson<{
    status?: string
    message?: string
    data?: unknown
  }>({
    endpoint: BACKEND_ENDPOINTS.masterTable.isinAssetMaster.view,
    method: "POST",
    body: { id },
    invalidMessage: "Failed to load master detail.",
    unavailableMessage: "Failed to load master detail.",
    timeoutMessage: "Master detail timed out.",
    connectionMessage: "Could not connect for master detail.",
  })

  if (status === 404) {
    return { notFound: true as const }
  }

  if (!response || response.status !== "success" || !isRecord(response.data)) {
    return {
      notFound: false as const,
      errorMessage:
        errorMessage || stringOrEmpty(response?.message) || "Failed to load master detail.",
      model: emptyModel(id),
      pibClassList: [] as ReturnType<typeof normalizePibClassList>,
      probabilities: { ac: {}, bank_count: 0, a_type: null, rows: [] as VoteRow[] },
    }
  }

  const data = response.data
  const modelRaw = isRecord(data.model) ? data.model : {}
  const probsRaw = isRecord(data.probabilities) ? data.probabilities : {}
  const pibClassList = normalizePibClassList(data.pibClassList)
  const acRaw = isRecord(probsRaw.ac) ? probsRaw.ac : {}
  const ac: Record<string, number> = {}
  for (const [k, v] of Object.entries(acRaw)) {
    ac[k] = Number(v)
  }
  const rows: VoteRow[] = Array.isArray(probsRaw.rows)
    ? probsRaw.rows.filter(isRecord).map((r) => ({
        isin: stringOrEmpty(r.isin),
        isin_name: stringOrEmpty(r.isin_name),
        bank_api_id: Number(r.bank_api_id),
        bank_name: stringOrEmpty(r.bank_name),
        api_category: stringOrEmpty(r.api_category),
        a_class: stringOrEmpty(r.a_class),
        a_type: stringOrEmpty(r.a_type),
        source: stringOrEmpty(r.source),
        updated_at: stringOrEmpty(r.updated_at),
      }))
    : []

  return {
    notFound: false as const,
    errorMessage: null as string | null,
    model: {
      id: stringOrEmpty(modelRaw.id) || id,
      isin: stringOrEmpty(modelRaw.isin),
      isinName: stringOrEmpty(modelRaw.isin_name),
      aClass: stringOrEmpty(modelRaw.a_class),
      aClassLabel: stringOrEmpty(data.a_class_label) || stringOrEmpty(modelRaw.a_class),
      aType: stringOrEmpty(modelRaw.a_type),
      pibClass: stringOrEmpty(modelRaw.pib_class),
      status: stringOrEmpty(modelRaw.status),
      statusLabel:
        stringOrEmpty(
          isRecord(data.statusList) ? data.statusList[stringOrEmpty(modelRaw.status)] : ""
        ) || stringOrEmpty(modelRaw.status),
      confidenceAc:
        modelRaw.confidence_ac == null || modelRaw.confidence_ac === ""
          ? null
          : Number(modelRaw.confidence_ac),
      updatedAt: stringOrEmpty(modelRaw.updated_at),
    },
    pibClassList,
    probabilities: {
      ac,
      bank_count: Number(probsRaw.bank_count ?? rows.length),
      a_type: probsRaw.a_type == null ? null : stringOrEmpty(probsRaw.a_type),
      rows,
    },
  }
}

type VoteRow = {
  isin: string
  isin_name: string
  bank_api_id: number
  bank_name: string
  api_category: string
  a_class: string
  a_type: string
  source: string
  updated_at: string
}

function emptyModel(id: string) {
  return {
    id,
    isin: "",
    isinName: "",
    aClass: "",
    aClassLabel: "",
    aType: "",
    pibClass: "",
    status: "",
    statusLabel: "",
    confidenceAc: null as number | null,
    updatedAt: "",
  }
}
