import { directionLabel } from "@/lib/utils";
import { useMemo } from "react";
import { useQuery } from "@tanstack/react-query";
import { useLocation, useParams } from "react-router-dom";
import {
  Alert,
  Badge,
  Box,
  Button,
  Grid,
  Group,
  Loader,
  Paper,
  Progress,
  RingProgress,
  Stack,
  Text,
  ThemeIcon,
} from "@mantine/core";
import {
  AlertCircle,
  ArrowRight,
  CheckCircle2,
  Clock,
  PackageCheck,
  RefreshCw,
  ShieldCheck,
} from "lucide-react";
import { Link } from "react-router-dom";

import { useAuth } from "@/auth/useAuth";
import {
  FREIGHT_PERMS,
  hasPermission,
  isDjiboutiGl,
} from "@/lib/permissions";

import { BookingChangesRequestedAlert } from "@/components/contracts/BookingChangesRequestedAlert";
import { ClearanceOpsTabs } from "@/components/contracts/ClearanceOpsTabs";
import { PageContainer } from "@/components/page/PageContainer";
import { PageHeader } from "@/components/page/PageHeader";
import { SectionCard } from "@/components/bookings/detail/SectionCard";
import { ContractClearanceReviewSection } from "@/components/contracts/ContractClearanceReviewSection";
import { GlUpcomingWindowsSection } from "@/components/contracts/GlUpcomingWindowsSection";
import { PhasedClearanceActionPanel } from "@/components/contracts/PhasedClearanceActionPanel";
import { QUERY_KEYS } from "@/constants/QUERY_KEYS";
import { useFileViewer } from "@/hooks/useFileViewer";
import { contractsService } from "@/services/contracts.service";
import { downloadBookingFile } from "@/services/files.service";
import {
  useBookingMilestones,
  useContractDetail,
} from "@/hooks/contracts/useContracts";

export default function ContractClearanceDetailPage() {
  const { id } = useParams<{ id: string }>();
  const { pathname } = useLocation();
  const { view, viewer } = useFileViewer();
  const { user } = useAuth();

  // The same detail page serves two hubs: the GL "Document Clearance" list and
  // the Operations "Clearance Documents" list. Point back-navigation at
  // whichever hub the user came through.
  const fromOpsHub = pathname.startsWith(
    "/dashboard/contracts/clearance-documents",
  );
  const hubHref = fromOpsHub
    ? "/dashboard/contracts/clearance-documents"
    : "/dashboard/contracts/clearance";
  const hubLabel = fromOpsHub ? "Clearance Documents" : "Document Clearance";

  const { data: contract, refetch: refetchContract } = useContractDetail(id);
  const {
    data: clearance,
    isLoading,
    isError,
    refetch,
  } = useQuery({
    queryKey: QUERY_KEYS.CONTRACTS.clearance(id ?? ""),
    queryFn: () => contractsService.getClearance(id!),
    enabled: Boolean(id),
  });

  const stats = useMemo(() => {
    const docs = (clearance?.documents ?? []).filter(
      (d) => d.uploadedBy === "customer",
    );
    const total = docs.length;
    const approved = docs.filter((d) => d.reviewStatus === "APPROVED").length;
    const queried = docs.filter((d) => d.reviewStatus === "QUERIED").length;
    const pending = total - approved - queried;
    const pct = total === 0 ? 0 : Math.round((approved / total) * 100);
    return { total, approved, queried, pending, pct };
  }, [clearance]);

  const reference = contract?.reference ?? "Clearance";
  // Path A (non-customs) → Operations reviews & finalizes; Path B (customs) → GL.
  // This page serves BOTH hubs (Ops "Clearance Documents" + GL "Document
  // Clearance"), so the reviewer is decided by the contract, not the hub — a
  // hardcoded value routes non-customs finalize to the GL endpoint and 409s.
  const selfClear = !contract?.customsClearingEnabled;
  const phasedCustoms =
    contract?.contractKind === "ONE_TIME" && Boolean(contract.customsClearingEnabled);
  const docsPhaseComplete =
    clearance?.milestones?.some(
      (m) => m.milestoneCode === "DOCUMENTS_APPROVED" && m.status === "COMPLETED",
    ) ?? false;
  const ready = clearance?.bookingReady === true;
  const docReviewLocked = phasedCustoms
    ? docsPhaseComplete
    : clearance?.clearanceStatus === "CLEARANCE_READY_FOR_BOOKING";
  const shipmentLocked = Boolean(
    contract?.status &&
      [
        "ACTIVE_SHIPMENT_IN_PROGRESS",
        "FULLY_EXECUTED",
        "CONTRACT_ACTIVE",
        "CONTRACT_CLOSED",
        "EXPIRED",
      ].includes(contract.status),
  );
  const linkedBookingId = useMemo(() => {
    // Prefer the clearance view's server-resolved linkedBookingId (same field the
    // GL Djibouti page uses). The contract's clearanceCycles[cycle].bookingId can
    // be null/stale for an export FCFS booking, which would disable
    // useBookingMilestones → empty milestones → the export "Payment & wagon
    // allocation" step reads FREIGHT_PAYMENT_SETTLED as not-done and stays stuck.
    const cycle = contract?.clearanceCycles?.find(
      (c) => c.cycleNumber === (contract?.clearanceCycleNumber ?? 1),
    );
    return clearance?.linkedBookingId ?? cycle?.bookingId ?? undefined;
  }, [clearance, contract]);
  const bookingAlreadyCreated = Boolean(linkedBookingId) || shipmentLocked;
  const canCreateBooking = ready && !bookingAlreadyCreated;
  const reviewReadOnly = shipmentLocked;
  const queriesLocked = Boolean(clearance?.preClearanceFinalized);
  const bookingHref = `/dashboard/contracts/${id}/create-booking`;
  // The GL-created booking expired unpaid — the slot is free again and GL
  // rebooks on the customer's behalf (customs bookings are never self-booked).
  const bookingExpired = clearance?.linkedBookingStatus === "EXPIRED";
  // Operations sent the GL-created booking back. GL owns customs bookings, so
  // the note and the resubmit belong here, not in the customer's portal.
  const bookingNeedsChanges =
    clearance?.linkedBookingStatus === "OPERATION_CHANGES_REQUESTED";
  const isGlBookingOwner =
    hasPermission(user, FREIGHT_PERMS.contracts.createBooking) &&
    !isDjiboutiGl(user);
  const canResubmitBooking = bookingNeedsChanges && isGlBookingOwner;
  const canRebook = bookingExpired && isGlBookingOwner;
  const rebookHref = linkedBookingId
    ? `${bookingHref}?copyFrom=${linkedBookingId}`
    : bookingHref;

  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>
        <Group justify="center" py={80} gap={10}>
          <Loader color="edr-green" />
          <Text c="dimmed">Loading clearance…</Text>
        </Group>
      </PageContainer>
    );
  }

  if (isError || !clearance) {
    return (
      <PageContainer>
        <PageHeader
          title="Clearance not found"
          backTo={hubHref}
          breadcrumbs={[
            { label: hubLabel, href: hubHref },
            { label: "Not found" },
          ]}
        />
        <Alert color="red" radius="md" icon={<AlertCircle size={16} />}>
          We couldn’t load this contract’s clearance.
        </Alert>
      </PageContainer>
    );
  }

  const workflowFiles = clearance.workflowFiles ?? [];

  return (
    <PageContainer>
      <Stack gap="lg">
        <PageHeader
          title={reference}
          backTo={hubHref}
          breadcrumbs={[
            { label: hubLabel, href: hubHref },
            { label: reference },
          ]}
          meta={
            bookingExpired ? (
              <Badge
                variant="light"
                color="orange"
                radius="sm"
                leftSection={<RefreshCw size={13} />}
              >
                Payment expired — rebook
              </Badge>
            ) : bookingAlreadyCreated ? (
              <Badge
                variant="light"
                color="blue"
                radius="sm"
                leftSection={<PackageCheck size={13} />}
              >
                Booking created
              </Badge>
            ) : ready ? (
              <Badge
                variant="light"
                color="edr-green"
                radius="sm"
                leftSection={<PackageCheck size={13} />}
              >
                Ready — create booking
              </Badge>
            ) : clearance.allApproved ? (
              <Badge
                variant="light"
                color="edr-green"
                radius="sm"
                leftSection={<CheckCircle2 size={13} />}
              >
                All approved
              </Badge>
            ) : (
              <Badge
                variant="light"
                color="gray"
                radius="sm"
                leftSection={<Clock size={13} />}
              >
                Review pending
              </Badge>
            )
          }
        />

        <ClearanceHero contract={contract} stats={stats} />

        {/* Windows on this contract's routes/direction only — tells GL ET when
            it can actually create the booking without checking the schedule board. */}
        {id ? <GlUpcomingWindowsSection contractId={id} /> : null}

        {bookingExpired ? (
          <Alert
            color="orange"
            radius="md"
            icon={<RefreshCw size={16} />}
            title="Booking expired — payment not received"
          >
            <Stack gap="sm" align="flex-start">
              <Text size="sm">
                The customer did not pay before the deadline, so the booking
                expired and its train slot was released. The contract slot is
                free again — GL Ethiopia can rebook on the customer&apos;s
                behalf without re-running clearance.
                {linkedBookingId ? (
                  <>
                    {" "}
                    <Text
                      component={Link}
                      to={`/dashboard/bookings/${linkedBookingId}/clearance`}
                      inherit
                      fw={600}
                      c="orange.8"
                    >
                      View expired booking →
                    </Text>
                  </>
                ) : null}
              </Text>
              {canRebook ? (
                <Button
                  component={Link}
                  to={rebookHref}
                  color="grape"
                  radius="md"
                  size="sm"
                  leftSection={<RefreshCw size={15} />}
                >
                  Rebook for customer
                </Button>
              ) : null}
            </Stack>
          </Alert>
        ) : bookingNeedsChanges && linkedBookingId ? (
          <BookingChangesRequestedAlert
            bookingId={linkedBookingId}
            reference={clearance.linkedBookingReference}
            note={clearance.linkedBookingReviewNote}
            scheduledDate={clearance.linkedBookingScheduledDate}
            canResubmit={canResubmitBooking}
            onResubmitted={() => {
              void refetch();
              void refetchContract();
              refetchBookingMilestonesIfLinked();
            }}
          />
        ) : bookingAlreadyCreated ? (
          <Alert
            color="blue"
            radius="md"
            icon={<PackageCheck size={16} />}
            title="Shipment booking created"
          >
            GL Ethiopia has created the shipment booking for this contract.
            {linkedBookingId ? (
              <>
                {" "}
                <Text
                  component={Link}
                  to={`/dashboard/bookings/${linkedBookingId}/clearance`}
                  inherit
                  fw={600}
                  c="blue.7"
                >
                  View booking →
                </Text>
              </>
            ) : null}
          </Alert>
        ) : canCreateBooking ? (
          <Alert
            color="edr-green"
            radius="md"
            icon={<PackageCheck size={16} />}
            title="Clearance complete"
          >
            Pre-booking clearance is complete. GL Ethiopia can create the shipment booking.
          </Alert>
        ) : null}

        <ClearanceOpsTabs
          bookingId={linkedBookingId}
          milestones={bookingMilestones}
          showOpsTabs={Boolean(linkedBookingId)}
          showWorkflowFilesTab={phasedCustoms}
          tradeDirection={contract?.tradeDirection ?? "IMPORT"}
          workflowFiles={workflowFiles}
          onViewFile={view}
          onDownloadFile={(f) => void downloadBookingFile(f.id, f.name)}
          clearanceTab={
            <Grid>
              <Grid.Col span={{ base: 12, lg: 7 }}>
                <ContractClearanceReviewSection
                  contractId={id!}
                  hideSummary
                  selfClear={selfClear}
                  readOnly={reviewReadOnly}
                  approvalsLocked={phasedCustoms && docReviewLocked}
                  queriesLocked={queriesLocked}
                  phasedCustoms={phasedCustoms}
                  onChanged={() => {
                    void refetch();
                    void refetchContract();
                    refetchBookingMilestonesIfLinked();
                  }}
                />
              </Grid.Col>

              <Grid.Col span={{ base: 12, lg: 5 }}>
                <Stack gap="md">
                  {phasedCustoms ? (
                    <PhasedClearanceActionPanel
                      contractId={id!}
                      bookingId={linkedBookingId}
                      bookingMilestones={bookingMilestones ?? []}
                      clearance={clearance}
                      tradeDirection={contract?.tradeDirection ?? "IMPORT"}
                      workflowFiles={workflowFiles}
                      roleMode="ET"
                      onChanged={() => {
                        void refetch();
                        refetchBookingMilestonesIfLinked();
                      }}
                      onViewFile={view}
                      onDownloadFile={(f) => void downloadBookingFile(f.id, f.name)}
                      bookingCreateHref={canCreateBooking ? bookingHref : undefined}
                      bookingCreated={bookingAlreadyCreated}
                    />
                  ) : (
                    <Box style={{ position: "sticky", top: 24 }}>
                      <SectionCard
                        icon={PackageCheck}
                        title="Review progress"
                        accent="edr-green"
                      >
                        <Stack align="center" gap="sm">
                          <RingProgress
                            size={140}
                            thickness={12}
                            roundCaps
                            sections={[{ value: stats.pct, color: "edr-green" }]}
                            label={
                              <Stack gap={0} align="center">
                                <Text fw={800} fz={26} lh={1}>
                                  {stats.pct}%
                                </Text>
                                <Text size="xs" c="dimmed">
                                  approved
                                </Text>
                              </Stack>
                            }
                          />
                          <Group gap="lg" justify="center">
                            <ProgressStat
                              color="edr-green"
                              label="Approved"
                              value={stats.approved}
                            />
                            <ProgressStat
                              color="red"
                              label="Queried"
                              value={stats.queried}
                            />
                            <ProgressStat
                              color="gray"
                              label="Pending"
                              value={stats.pending}
                            />
                          </Group>
                        </Stack>
                      </SectionCard>
                    </Box>
                  )}
                </Stack>
              </Grid.Col>
            </Grid>
          }
        />
      </Stack>
      {viewer}
    </PageContainer>
  );
}

function ClearanceHero({
  contract,
  stats,
}: {
  contract: ReturnType<typeof useContractDetail>["data"];
  stats: { pct: number; approved: number; total: number };
}) {
  const direction = contract?.tradeDirection ?? "—";
  const serviceName = contract?.serviceType?.serviceName ?? null;
  const customs =
    contract?.serviceType?.includesCustoms ??
    contract?.customsClearingEnabled ??
    false;
  const routes = [...(contract?.routes ?? [])].sort(
    (a, b) => a.sortOrder - b.sortOrder,
  );
  const origin =
    routes[0]?.originYard?.label ?? routes[0]?.originYard?.code ?? "Origin";
  const last = routes[routes.length - 1] ?? routes[0];
  const destination =
    last?.destinationYard?.label ??
    last?.destinationYard?.code ??
    "Destination";

  return (
    <Paper withBorder radius="md" p="lg">
      <Group justify="space-between" align="flex-start" wrap="wrap" gap="lg">
        <Group gap="md" wrap="nowrap" style={{ minWidth: 0 }}>
          <ThemeIcon variant="light" color="edr-green" radius="md" size={52}>
            <ShieldCheck size={26} />
          </ThemeIcon>
          <Box style={{ minWidth: 0 }}>
            <Group gap={8} wrap="nowrap">
              <Text fw={800} fz={20} c="edr-text" truncate>
                {contract?.reference ?? "Clearance"}
              </Text>
              <Badge
                size="sm"
                variant="light"
                color={direction === "IMPORT" ? "edr-green" : "gray"}
                radius="sm"
              >
                {directionLabel(direction)}
              </Badge>
              {customs ? (
                <Badge
                  size="sm"
                  variant="light"
                  color="edr-green"
                  radius="sm"
                  leftSection={<ShieldCheck size={12} />}
                >
                  Customs
                </Badge>
              ) : (
                <Badge size="sm" variant="light" color="gray" radius="sm">
                  No customs
                </Badge>
              )}
            </Group>
            {serviceName && (
              <Text size="sm" fw={600} c="edr-text" mt={6} truncate maw={280}>
                {serviceName}
              </Text>
            )}
            <Group gap={8} mt={6} wrap="nowrap">
              <Text size="sm" fw={600} truncate maw={160}>
                {origin}
              </Text>
              <ArrowRight size={15} className="shrink-0 text-muted-foreground" />
              <Text size="sm" fw={600} truncate maw={160}>
                {destination}
              </Text>
            </Group>
          </Box>
        </Group>

        <Box style={{ minWidth: 200, flex: 1, maxWidth: 320 }}>
          <Group justify="space-between" mb={6}>
            <Text size="xs" c="dimmed" fw={600}>
              Document review
            </Text>
            <Text size="xs" c="dimmed">
              {stats.approved}/{stats.total}
            </Text>
          </Group>
          <Progress value={stats.pct} color="edr-green" radius="xl" size="md" />
        </Box>
      </Group>
    </Paper>
  );
}

function ProgressStat({
  color,
  label,
  value,
}: {
  color: string;
  label: string;
  value: number;
}) {
  return (
    <Stack gap={2} align="center">
      <Text fw={700} fz={18} c="edr-text">
        {value}
      </Text>
      <Group gap={4} wrap="nowrap">
        <Box
          style={{
            width: 7,
            height: 7,
            borderRadius: 999,
            background: `var(--mantine-color-${color}-6)`,
          }}
        />
        <Text fz="11px" c="dimmed">
          {label}
        </Text>
      </Group>
    </Stack>
  );
}
