"use client"

import Link from "next/link"
import { useRouter } from "next/navigation"
import { useState } from "react"
import { GitCompareArrows, Settings } from "lucide-react"

import { ListPageCard } from "@/app/dashboard/_components"
import { XmlApiErrorBanner } from "@/components/xml-apis/shared/xml-api-error-banner"
import { FRONTEND_ROUTES } from "@/config/frontend-routes"
import { dashboardCsrfHeader } from "@/lib/csrf.client"
import type { IdLabelMap, PosReconV2Run } from "@/components/xml-apis/pos-recon-v2/types"
import { PosReconV2RunForm } from "@/components/xml-apis/pos-recon-v2/components/pos-recon-v2-run-form"
import { PosReconV2Table } from "@/components/xml-apis/pos-recon-v2/components/pos-recon-v2-table"

type Props = {
  initialData: PosReconV2Run[]
  initialTotalCount: number
  initialPage: number
  initialPageSize: number
  initialPageCount: number
  initialCorporateId: number
  initialBankApiId: number
  corporateDbOptions: IdLabelMap
  bankApiOptions: IdLabelMap
  initialUploads: IdLabelMap
  initialErrorMessage?: string | null
}

type UploadOption = { id: number; label: string }

function uploadsMapToNewestFirst(map: IdLabelMap): UploadOption[] {
  return Object.entries(map)
    .map(([id, label]) => ({ id: Number(id), label }))
    .filter((item) => Number.isFinite(item.id) && item.id > 0)
    .sort((a, b) => {
      const dateA = a.label.match(/\d{4}-\d{2}-\d{2}/)?.[0] ?? ""
      const dateB = b.label.match(/\d{4}-\d{2}-\d{2}/)?.[0] ?? ""
      if (dateA !== dateB) return dateB.localeCompare(dateA)
      return b.id - a.id
    })
}

export function PosReconV2ListPage({
  initialData,
  initialTotalCount,
  initialPage,
  initialPageSize,
  initialPageCount,
  initialCorporateId,
  initialBankApiId,
  corporateDbOptions,
  bankApiOptions,
  initialUploads,
  initialErrorMessage = null,
}: Props) {
  const router = useRouter()
  const [errorMessage, setErrorMessage] = useState(initialErrorMessage)
  const [busy, setBusy] = useState(false)
  const [uploadItems, setUploadItems] = useState(() => uploadsMapToNewestFirst(initialUploads))
  const [corporateId, setCorporateId] = useState(initialCorporateId)
  const [bankApiId, setBankApiId] = useState(initialBankApiId)

  async function loadUploads(nextBankId: number) {
    setBankApiId(nextBankId)
    if (!nextBankId) {
      setUploadItems([])
      return
    }
    setErrorMessage(null)
    try {
      const res = await fetch(FRONTEND_ROUTES.xmlApis.posReconV2.uploads, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          ...dashboardCsrfHeader(),
        },
        body: JSON.stringify({ bank_api_id: nextBankId }),
      })
      const json = await res.json().catch(() => ({}))
      if (!res.ok || json.status === "error") {
        setUploadItems([])
        setErrorMessage(
          typeof json?.message === "string" && json.message.trim()
            ? json.message
            : "Could not load POS uploads for this bank."
        )
        return
      }
      const items = Array.isArray(json?.data?.items) ? json.data.items : []
      // Backend already returns date DESC; keep that order (do not round-trip via Object.entries).
      const nextItems: UploadOption[] = items
        .map((item: { id?: unknown; label?: unknown }) => ({
          id: Number(item.id) || 0,
          label: String(item.label || item.id || ""),
        }))
        .filter((item: UploadOption) => item.id > 0)
      setUploadItems(nextItems)
      if (nextItems.length === 0) {
        setErrorMessage("No POS uploads found for this bank.")
      }
    } catch {
      setUploadItems([])
      setErrorMessage("Could not load POS uploads for this bank.")
    }
  }

  async function onReconcile(uploadId: number) {
    if (!corporateId || !uploadId) {
      setErrorMessage("Select corporate DB and a POS upload.")
      return
    }
    setBusy(true)
    setErrorMessage(null)
    try {
      const res = await fetch(FRONTEND_ROUTES.xmlApis.posReconV2.run, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          ...dashboardCsrfHeader(),
        },
        body: JSON.stringify({ upload_id: uploadId, corporate_id: corporateId }),
      })
      const json = await res.json().catch(() => ({}))
      if (!res.ok || json.status === "error") {
        setErrorMessage(json.message || "Reconcile failed.")
        return
      }
      const runId = Number(json?.data?.run?.id || 0)
      if (runId > 0) {
        router.push(`/dashboard/xml-apis/pos-recon-v2/${runId}?corporate_id=${corporateId}`)
        return
      }
      router.refresh()
    } finally {
      setBusy(false)
    }
  }

  function onCorporateChange(next: number) {
    setCorporateId(next)
    const params = new URLSearchParams()
    if (next) params.set("corporate_id", String(next))
    if (bankApiId) params.set("bank_api_id", String(bankApiId))
    router.push(`/dashboard/xml-apis/pos-recon-v2?${params.toString()}`)
  }

  return (
    <ListPageCard
      icon={GitCompareArrows}
      title="POS Recon v2"
      description="Safra + BOS + Nomura + LGT (CH & SG) + UBP + Swiss Quote + CUB (Bahamas & ME) + UBS 1-on-1 POS vs Overall Summary reconciliation."
      breadcrumb={[{ label: "XML API" }, { label: "POS Recon v2" }]}
      actions={
        <Link
          href="/dashboard/xml-apis/pos-recon-v2/settings"
          className="inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground"
        >
          <Settings className="h-4 w-4" />
          Settings
        </Link>
      }
    >
      <XmlApiErrorBanner message={errorMessage} />
      <PosReconV2RunForm
        corporateId={corporateId}
        bankApiId={bankApiId}
        corporateDbOptions={corporateDbOptions}
        bankApiOptions={bankApiOptions}
        uploads={uploadItems}
        busy={busy}
        onCorporateChange={onCorporateChange}
        onBankChange={loadUploads}
        onReconcile={onReconcile}
      />
      <div className="mt-6">
        <PosReconV2Table
          data={initialData}
          totalCount={initialTotalCount}
          page={initialPage}
          pageSize={initialPageSize}
          pageCount={initialPageCount}
          corporateId={corporateId}
          bankApiOptions={bankApiOptions}
        />
      </div>
    </ListPageCard>
  )
}
