import { useMemo } from "react";
import { Box, Center, Group, Loader, Stack, Text } from "@mantine/core";
import { FileText, FolderOpen } from "lucide-react";
import { useQuery } from "@tanstack/react-query";
import type { Freight } from "@edr/types";

import { bookingsService } from "@/services/bookings.service";
import { downloadBookingFile } from "@/services/files.service";
import { useFileViewer } from "@/hooks/useFileViewer";
import { ClearanceWorkflowFilesPanel } from "@/components/contracts/ClearanceWorkflowFilesPanel";
import { PhasedUploadedFileRow } from "@/components/contracts/PhasedUploadedFileRow";
import { SectionCard } from "./SectionCard";

interface LabeledFile {
  label: string;
  file: { id: string; name: string };
}

/**
 * Every document tied to a booking, in one tab: the customer/GL clearance
 * documents, the customs workflow files (declaration/duty/transit/Djibouti),
 * the duty-tax notice, and the final invoice + payment slip. All fetched from
 * the booking's clearance view (the only endpoint that surfaces booking files),
 * each with inline view + download.
 */
export function BookingDocumentsPanel({ bookingId }: { bookingId: string }) {
  const { view, viewer } = useFileViewer();

  const { data: clearance, isLoading, isError } = useQuery({
    queryKey: ["clearance", bookingId],
    queryFn: () => bookingsService.getClearance(bookingId),
  });

  const onDownload = (f: { id: string; name: string }) =>
    void downloadBookingFile(f.id, f.name);

  // Uploaded customer + GL clearance documents (skip the not-yet-uploaded slots).
  const clearanceDocs = useMemo<
    Array<{ doc: Freight.ClearanceDocument; file: { id: string; name: string } }>
  >(
    () =>
      (clearance?.documents ?? [])
        .filter((d) => d.file)
        .map((d) => ({ doc: d, file: d.file! })),
    [clearance],
  );

  const workflowFiles = useMemo(
    () => (clearance?.workflowFiles ?? []).filter((f) => f.file),
    [clearance],
  );

  // Duty notice + final invoice + payment slip — loose files that don't ride in
  // the documents/workflow arrays.
  const otherFiles = useMemo<LabeledFile[]>(() => {
    const rows: LabeledFile[] = [];
    const notice = clearance?.dutyAdvice?.noticeFile;
    if (notice) rows.push({ label: "Duty & tax notice", file: notice });
    const inv = clearance?.finalInvoice;
    if (inv?.invoiceFile)
      rows.push({ label: `Final invoice · ${inv.invoiceNumber}`, file: inv.invoiceFile });
    if (inv?.slipFile)
      rows.push({ label: "Final invoice payment slip", file: inv.slipFile });
    return rows;
  }, [clearance]);

  if (isLoading) {
    return (
      <Center py={60}>
        <Group gap={10}>
          <Loader color="edr-green" />
          <Text c="dimmed">Loading documents…</Text>
        </Group>
      </Center>
    );
  }

  const hasAny =
    clearanceDocs.length > 0 || workflowFiles.length > 0 || otherFiles.length > 0;

  if (isError || !hasAny) {
    return (
      <SectionCard icon={FolderOpen} title="Documents" accent="edr-green">
        <Center py={28}>
          <Stack align="center" gap={6}>
            <FolderOpen size={26} color="var(--mantine-color-gray-5)" />
            <Text fw={600}>No documents yet</Text>
            <Text size="sm" c="dimmed" ta="center" maw={360}>
              {isError
                ? "Couldn’t load this booking’s documents."
                : "Documents attached to this booking will appear here as they’re uploaded."}
            </Text>
          </Stack>
        </Center>
      </SectionCard>
    );
  }

  return (
    <Stack gap="lg">
      {clearanceDocs.length > 0 && (
        <SectionCard icon={FileText} title="Clearance documents" accent="edr-green">
          <Stack gap={8}>
            {clearanceDocs.map(({ doc, file }) => (
              <PhasedUploadedFileRow
                key={doc.fileKey}
                label={`${doc.label}${doc.uploadedBy === "gl" ? " · GL" : ""}`}
                file={file}
                onView={view}
                onDownload={onDownload}
                compact
              />
            ))}
          </Stack>
        </SectionCard>
      )}

      {workflowFiles.length > 0 && (
        <ClearanceWorkflowFilesPanel
          files={workflowFiles}
          onView={view}
          onDownload={onDownload}
        />
      )}

      {otherFiles.length > 0 && (
        <SectionCard icon={FileText} title="Invoices & notices" accent="edr-green">
          <Stack gap={8}>
            {otherFiles.map((row) => (
              <PhasedUploadedFileRow
                key={row.file.id}
                label={row.label}
                file={row.file}
                onView={view}
                onDownload={onDownload}
                compact
              />
            ))}
          </Stack>
        </SectionCard>
      )}

      <Box>{viewer}</Box>
    </Stack>
  );
}
