import { directionLabel } from "@/lib/utils";
import { useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { useParams } from "react-router-dom";
import {
  Alert,
  Badge,
  Box,
  Button,
  Grid,
  Group,
  Loader,
  Stack,
  Tabs,
  Text,
  ThemeIcon,
} from "@mantine/core";
import {
  AlertCircle,
  AlertTriangle,
  ClipboardList,
  FileText,
  Upload,
} from "lucide-react";
import type { Freight } from "@edr/types";

import { useAuth } from "@/auth/useAuth";
import { FREIGHT_PERMS, hasPermission } from "@/lib/permissions";
import type { BookingDetail } from "@/types/booking";

import { PageContainer } from "@/components/page/PageContainer";
import { PageHeader } from "@/components/page/PageHeader";
import { ClearanceReviewSection } from "@/components/bookings/detail/ClearanceReviewSection";
import { ContractClearanceReviewSection } from "@/components/contracts/ContractClearanceReviewSection";
import { ClearanceWorkflowFilesPanel } from "@/components/contracts/ClearanceWorkflowFilesPanel";
import {
  GlClearanceUploadModal,
  type GlClearanceUploadKind,
} from "@/components/contracts/GlClearanceUploadModal";
import { PhasedClearanceActionPanel } from "@/components/contracts/PhasedClearanceActionPanel";
import { TransitAssigneePanel } from "@/components/contracts/TransitAssigneePanel";
import { SectionCard } from "@/components/bookings/detail/SectionCard";
import { IncidentReportCard } from "@/components/contracts/gl-actions/IncidentReportCard";
import { findWorkflowFile } from "@/components/contracts/PhasedUploadedFileRow";
import { useFileViewer } from "@/hooks/useFileViewer";
import { useBookingMilestones } from "@/hooks/contracts/useContracts";
import { contractsService } from "@/services/contracts.service";
import { bookingsService } from "@/services/bookings.service";
import { downloadBookingFile } from "@/services/files.service";

type GlClearanceDetail =
  | {
      kind: "contract";
      reference: string;
      tradeDirection: string;
      clearance: Freight.ContractClearanceView;
    }
  | {
      kind: "booking";
      reference: string;
      tradeDirection: string;
      clearance: Freight.ClearanceView;
      booking: BookingDetail;
    };

async function loadGlClearanceDetail(id: string): Promise<GlClearanceDetail> {
  try {
    // Probe the contract endpoints first; a booking-id row 404s here by design
    // and falls back to the booking lookup below. Suppress the global error
    // modal so that expected 404 never surfaces to the user.
    const [clearance, contract] = await Promise.all([
      contractsService.getClearance(id, { suppressErrorModal: true }),
      contractsService.getById(id, { suppressErrorModal: true }),
    ]);
    return {
      kind: "contract",
      reference: contract.reference,
      tradeDirection: contract.tradeDirection,
      clearance,
    };
  } catch {
    const [clearance, booking] = await Promise.all([
      bookingsService.getClearance(id),
      bookingsService.getById(id),
    ]);
    return {
      kind: "booking",
      reference: booking.reference,
      tradeDirection: booking.tradeDirection,
      clearance,
      booking,
    };
  }
}

/** Djibouti GL clearance detail — RO/DO upload and read-only upstream context. */
export default function GlClearanceDetailPage() {
  const { id } = useParams<{ id: string }>();
  const { user } = useAuth();
  const { view, viewer } = useFileViewer();
  const [uploadKind, setUploadKind] = useState<GlClearanceUploadKind | null>(null);

  const { data, isLoading, isError, refetch } = useQuery({
    queryKey: ["gl-clearance-detail", id],
    queryFn: () => loadGlClearanceDetail(id!),
    enabled: Boolean(id),
  });

  const linkedBookingId =
    data?.kind === "contract" ? (data.clearance.linkedBookingId ?? undefined) : undefined;
  const { data: bookingMilestones, refetch: refetchBookingMilestones } =
    useBookingMilestones(linkedBookingId);

  // react-query's imperative refetch() ignores `enabled`, so calling it while
  // linkedBookingId is still undefined (pre-booking clearance) would fire
  // GET /contracts/bookings/undefined/milestones → 400 (uuid expected). Guard it.
  const refetchBookingMilestonesIfLinked = () => {
    if (linkedBookingId) void refetchBookingMilestones();
  };

  if (isLoading) {
    return (
      <PageContainer>
        <Stack align="center" py={80}>
          <Loader color="edr-green" />
          <Text c="dimmed">Loading clearance…</Text>
        </Stack>
      </PageContainer>
    );
  }

  if (isError || !data) {
    return (
      <PageContainer>
        <Alert color="red" icon={<AlertCircle size={16} />}>
          Could not load clearance for this item.
        </Alert>
      </PageContainer>
    );
  }

  const backTo = "/dashboard/gl-djibouti/clearance";
  const workflowFiles = data.clearance.workflowFiles ?? [];
  const workflowFileCount = workflowFiles.filter((f) => f.file).length;
  const isImport = data.tradeDirection === "IMPORT";
  const hasDo = Boolean(findWorkflowFile(workflowFiles, "delivery_order"));
  const hasRo = Boolean(findWorkflowFile(workflowFiles, "release_order"));
  // DO upload is un-gated — Djibouti GL may attach it at any point, any file type.
  const canUploadDo = isImport;
  const vesselDepartureDate =
    "vesselDepartureDate" in data.clearance
      ? (data.clearance.vesselDepartureDate ?? null)
      : null;
  // Incident reporting attaches to a booking; a contract-level clearance can
  // only report against its linked booking once one exists.
  const incidentBookingId = data.kind === "booking" ? id : linkedBookingId;

  // The shipment booking instance backing this clearance (per-booking GENERAL
  // customs). Bare until GL completes it: no cargo, no price.
  const shipmentBooking = data.kind === "booking" ? data.booking : null;
  const bookingCompleted = Number(shipmentBooking?.totalAmount ?? 0) > 0;
  // Import boundary (DO collected) / export boundary (release) reached →
  // clearance is ready and GL creates the real booking. Show the create-booking
  // CTA here so the GL user who finishes the DJ step isn't left without a next
  // action. Permission-gated so only booking creators (GL Ethiopia) see it.
  const canCompleteBooking =
    shipmentBooking?.status === "CLEARANCE_READY" &&
    Boolean(shipmentBooking?.contractId) &&
    !bookingCompleted &&
    hasPermission(user, FREIGHT_PERMS.contracts.createBooking);

  return (
    <PageContainer>
      <Stack gap="lg">
        <PageHeader
          title={data.reference}
          backTo={backTo}
          breadcrumbs={[
            { label: "GL Djibouti Clearance", href: backTo },
            { label: data.reference },
          ]}
          meta={
            <Badge variant="light" color={isImport ? "edr-green" : "gray"} radius="sm">
              {directionLabel(data.tradeDirection)}
            </Badge>
          }
          action={
            <Group gap="sm">
              {isImport ? (
                <Button
                  variant={canCompleteBooking ? "default" : "filled"}
                  color="edr-green"
                  leftSection={<Upload size={16} />}
                  disabled={!canUploadDo}
                  onClick={() => setUploadKind("do")}
                >
                  {hasDo ? "Replace DO" : "Upload DO"}
                </Button>
              ) : (
                <Button
                  variant={canCompleteBooking ? "default" : "filled"}
                  color="edr-green"
                  leftSection={<Upload size={16} />}
                  onClick={() => setUploadKind("ro")}
                >
                  {hasRo ? "Replace RO" : "Upload RO"}
                </Button>
              )}
            </Group>
          }
        />

        <Tabs defaultValue="workflow" keepMounted={false}>
          <Tabs.List mb="md">
            <Tabs.Tab value="workflow" leftSection={<ClipboardList size={14} />}>
              Clearance workflow
            </Tabs.Tab>
            <Tabs.Tab
              value="documents"
              leftSection={<FileText size={14} />}
              rightSection={
                workflowFileCount > 0 ? (
                  <Badge size="xs" variant="light" color="edr-green" circle>
                    {workflowFileCount}
                  </Badge>
                ) : undefined
              }
            >
              Customs documents (all steps)
            </Tabs.Tab>
            {incidentBookingId ? (
              <Tabs.Tab value="incidents" leftSection={<AlertTriangle size={14} />}>
                Incidents
              </Tabs.Tab>
            ) : null}
          </Tabs.List>

          <Tabs.Panel value="workflow">
            {/* GL Ethiopia cannot file the customs declaration until this desk
                names the officer handling the shipment in transit, so the ask
                sits above everything else on the page. */}
            {data.kind === "contract" ? (
              <Box mb="md">
                <TransitAssigneePanel
                  contractId={id!}
                  transitAssignee={data.clearance.transitAssignee}
                  side="DJ"
                  readOnly={
                    !hasPermission(user, FREIGHT_PERMS.contracts.clearanceDjActions)
                  }
                  onChanged={() => void refetch()}
                />
              </Box>
            ) : null}

            <Grid>
              <Grid.Col span={{ base: 12, lg: 7 }}>
                {data.kind === "booking" ? (
                  <ClearanceReviewSection
                    bookingId={id!}
                    hideSummary
                    readOnly
                    phasedCustoms
                  />
                ) : (
                  <ContractClearanceReviewSection
                    contractId={id!}
                    hideSummary
                    selfClear={false}
                    readOnly
                    phasedCustoms
                  />
                )}
              </Grid.Col>

              <Grid.Col span={{ base: 12, lg: 5 }}>
                <PhasedClearanceActionPanel
                  contractId={data.kind === "contract" ? id : undefined}
                  bookingId={data.kind === "booking" ? id : linkedBookingId}
                  // For a per-booking instance, "created" means COMPLETED (has
                  // cargo/price), not merely that a booking row exists — a bare
                  // instance is not yet a real booking. Contract-level clearance
                  // keeps its linked-booking signal.
                  bookingCreated={
                    data.kind === "booking"
                      ? bookingCompleted
                      : Boolean(linkedBookingId)
                  }
                  bookingMilestones={
                    data.kind === "booking"
                      ? (data.clearance.milestones ?? [])
                      : (bookingMilestones ?? [])
                  }
                  clearance={data.clearance}
                  tradeDirection={data.tradeDirection}
                  workflowFiles={workflowFiles}
                  roleMode="DJ"
                  useUploadModals
                  onUploadDoRequest={() => setUploadKind("do")}
                  onUploadRoRequest={() => setUploadKind("ro")}
                  onChanged={() => {
                    void refetch();
                    refetchBookingMilestonesIfLinked();
                  }}
                  onViewFile={view}
                  onDownloadFile={(f) => void downloadBookingFile(f.id, f.name)}
                />
              </Grid.Col>
            </Grid>
          </Tabs.Panel>

          <Tabs.Panel value="documents">
            {workflowFiles.length > 0 ? (
              <ClearanceWorkflowFilesPanel
                files={workflowFiles}
                title="Customs documents (all steps)"
                onView={view}
                onDownload={(f) => void downloadBookingFile(f.id, f.name)}
              />
            ) : (
              <Box
                py={48}
                style={{
                  borderRadius: 12,
                  border: "1px dashed var(--mantine-color-gray-4)",
                  background: "var(--mantine-color-gray-0)",
                  textAlign: "center",
                }}
              >
                <Stack gap={8} align="center">
                  <ThemeIcon variant="light" color="gray" radius="xl" size={48}>
                    <FileText size={22} />
                  </ThemeIcon>
                  <Text size="sm" c="dimmed" maw={360}>
                    No customs workflow documents uploaded yet. Files from Ethiopia-side
                    clearance and your DO/RO uploads will appear here.
                  </Text>
                </Stack>
              </Box>
            )}
          </Tabs.Panel>

          {incidentBookingId ? (
            <Tabs.Panel value="incidents">
              <SectionCard icon={AlertTriangle} title="Incident reports" accent="edr-green">
                <Stack gap="sm">
                  <Text size="sm" c="dimmed">
                    Log container or seal issues discovered during clearance handling.
                  </Text>
                  <IncidentReportCard bookingId={incidentBookingId} />
                </Stack>
              </SectionCard>
            </Tabs.Panel>
          ) : null}
        </Tabs>
      </Stack>

      <GlClearanceUploadModal
        opened={uploadKind != null}
        kind={uploadKind}
        onClose={() => setUploadKind(null)}
        entityId={id!}
        isBooking={data.kind === "booking"}
        workflowFiles={workflowFiles}
        vesselDepartureDate={vesselDepartureDate}
        vesselArrivalDate={data.clearance.vesselArrivalDate}
        doCollectedDate={data.clearance.doCollectedDate}
        onSuccess={() => void refetch()}
        onPreview={view}
      />
      {viewer}
    </PageContainer>
  );
}
