"use client"

import Link from "next/link"
import * as React from "react"
import { Suspense } from "react"
import { ArrowLeft, FileX2 } from "lucide-react"

import { Button } from "@/components/ui/button"
import {
  Empty,
  EmptyContent,
  EmptyDescription,
  EmptyHeader,
  EmptyMedia,
  EmptyTitle,
} from "@/components/ui/empty"
import { UploadXmlImportFooter } from "@/components/xml-apis/upload-xml/components/upload-xml-import-footer"
import { UploadXmlImportHeader } from "@/components/xml-apis/upload-xml/components/upload-xml-import-header"
import { UploadXmlImportShell } from "@/components/xml-apis/upload-xml/components/upload-xml-import-shell"
import { UploadXmlImportSkeleton } from "@/components/xml-apis/upload-xml/components/upload-xml-import-skeleton"
import { UploadXmlImportWorkspace } from "@/components/xml-apis/upload-xml/components/upload-xml-import-workspace"
import { useUploadXmlImport } from "@/components/xml-apis/upload-xml/hooks/use-upload-xml-import"
import type { UploadXmlBulkProcessSnapshot } from "@/components/xml-apis/upload-xml/_lib/import-grid-utils"
import type { UploadXmlImportView } from "@/components/xml-apis/upload-xml/types"

type UploadXmlImportPageProps = {
  uploadId: string
  initialView?: UploadXmlImportView | null
  initialErrorMessage?: string | null
  serverResolved?: boolean
}

function UploadXmlImportPageContent({
  uploadId,
  initialView = null,
  initialErrorMessage = null,
  serverResolved = false,
}: UploadXmlImportPageProps) {
  const { view, isLoading, errorMessage, page, reload } = useUploadXmlImport(uploadId, {
    initialView,
    initialErrorMessage,
    serverResolved,
  })

  const resolveInsertedColumnIds = React.useCallback((importView: UploadXmlImportView) => {
    // Portal-inserted only — a pending temp_id means the row already exists in
    // mw_temp_transactions but has not been added to the customer portal yet.
    // Keep sending temp_id on save so ajax_save can upsert; do not treat it as done.
    return new Set(
      importView.recordColumns
        .filter((column) => column.isInserted)
        .map((column) => column.id)
    )
  }, [])

  const [savedColumnIds, setSavedColumnIds] = React.useState<Set<string>>(() =>
    initialView ? resolveInsertedColumnIds(initialView) : new Set()
  )

  // Track the upload/page we last synced against. Navigating to a different
  // upload or page is an authoritative reset; a plain view refresh (e.g. after
  // an insert) must merge — never replace — so optimistic inserts aren't lost
  // when the backend hasn't yet reported them as inserted.
  const syncedKeyRef = React.useRef<string | null>(null)

  React.useEffect(() => {
    if (!view) {
      syncedKeyRef.current = null
      setSavedColumnIds(new Set())
      return
    }

    const key = `${uploadId}::${page}`
    const serverInserted = resolveInsertedColumnIds(view)

    setSavedColumnIds((current) => {
      if (syncedKeyRef.current !== key) {
        syncedKeyRef.current = key
        return serverInserted
      }
      if (serverInserted.size === 0) return current
      const next = new Set(current)
      for (const columnId of serverInserted) next.add(columnId)
      return next
    })
  }, [uploadId, page, resolveInsertedColumnIds, view])

  const handleRecordSaved = React.useCallback((columnId: string) => {
    setSavedColumnIds((current) => {
      if (current.has(columnId)) return current
      const next = new Set(current)
      next.add(columnId)
      return next
    })
  }, [])

  const handleRecordsSaved = React.useCallback((columnIds: string[]) => {
    setSavedColumnIds((current) => {
      const next = new Set(current)
      for (const columnId of columnIds) {
        next.add(columnId)
      }
      return next
    })
  }, [])

  const bulkProcessStateRef = React.useRef<UploadXmlBulkProcessSnapshot | null>(null)
  const handleBulkProcessStateChange = React.useCallback(
    (snapshot: UploadXmlBulkProcessSnapshot) => {
      bulkProcessStateRef.current = snapshot
    },
    []
  )
  const getBulkProcessState = React.useCallback(
    () => bulkProcessStateRef.current,
    []
  )

  if (isLoading) {
    return <UploadXmlImportSkeleton />
  }

  if (!view) {
    const detailMessage = errorMessage ?? initialErrorMessage
    const emptyXml =
      typeof detailMessage === "string" &&
      /contains no records|empty <RECORDS\/>|no import records were returned/i.test(
        detailMessage
      )

    return (
      <UploadXmlImportShell>
        <div className="flex min-h-0 flex-1 items-center justify-center p-6">
          <Empty className="max-w-md border border-border/60 bg-muted/10 py-12">
            <EmptyHeader>
              <EmptyMedia variant="icon" className="size-12 rounded-xl bg-destructive/10 text-destructive [&_svg:not([class*='size-'])]:size-6">
                <FileX2 />
              </EmptyMedia>
              <EmptyTitle className="text-base">
                {emptyXml ? "XML file has no records" : "Upload XML record not found"}
              </EmptyTitle>
              <EmptyDescription>
                {detailMessage
                  ? detailMessage
                  : "This upload may have been deleted, or the link is no longer valid."}
              </EmptyDescription>
            </EmptyHeader>
            <EmptyContent>
              <p className="rounded-md bg-muted px-2.5 py-1 font-mono text-muted-foreground text-xs">
                ID {uploadId}
              </p>
              <Button variant="outline" size="sm" className="mt-1 gap-1.5" asChild>
                <Link href="/dashboard/xml-apis/upload-xml">
                  <ArrowLeft className="size-3.5" />
                  Back to upload XML list
                </Link>
              </Button>
            </EmptyContent>
          </Empty>
        </div>
      </UploadXmlImportShell>
    )
  }

  return (
    <UploadXmlImportShell>
      <div className="flex min-h-0 min-w-0 flex-1 flex-col">
        <UploadXmlImportHeader view={view} />
        <UploadXmlImportWorkspace
          uploadId={uploadId}
          view={view}
          savedColumnIds={savedColumnIds}
          onRecordSaved={handleRecordSaved}
          onBulkProcessStateChange={handleBulkProcessStateChange}
        />
        
        <UploadXmlImportFooter
          uploadId={uploadId}
          view={view}
          savedColumnIds={savedColumnIds}
          getBulkProcessState={getBulkProcessState}
          onRefresh={reload}
          onRecordsSaved={handleRecordsSaved}
        />
      </div>
    </UploadXmlImportShell>
  )
}

export function UploadXmlImportPage(props: UploadXmlImportPageProps) {
  return (
    <Suspense fallback={<UploadXmlImportSkeleton />}>
      <UploadXmlImportPageContent {...props} />
    </Suspense>
  )
}
