import { directionLabel } from "@/lib/utils";
import { useNavigate, useParams, useSearchParams } from "react-router-dom";
import { useQuery } from "@tanstack/react-query";
import {
  AlertTriangle,
  ArrowLeft,
  ArrowRight,
  Box as BoxIcon,
  Building2,
  Calendar,
  CalendarClock,
  Download,
  FileSignature,
  FileText,
  Files,
  Flame,
  LayoutGrid,
  Package,
  Receipt,
  RefreshCw,
  Route as RouteIcon,
  ShieldCheck,
  Snowflake,
  Users,
} from "lucide-react";
import {
  Alert,
  Badge,
  Box,
  Button,
  Center,
  Container,
  Grid,
  Group,
  Loader,
  Paper,
  Stack,
  Tabs,
  Text,
  Title,
} from "@mantine/core";

import toast from "react-hot-toast";

import "@/components/overview/overview.css";
import { PageContainer } from "@/components/page";
import Breadcrumbs from "@/components/ui/Breadcrumbs";
import { SectionCard } from "@/components/bookings/detail/SectionCard";
import { detailStyles } from "@/components/bookings/detail/booking-detail.styles";
import { ContractStatusBadge } from "@/components/contracts/ContractStatusBadge";
import { ContractWorkflowStepper } from "@/components/contracts/ContractWorkflowStepper";
import { ContractActionsToolbar } from "@/components/contracts/ContractActionsToolbar";
import { ContractApprovalStepsCard } from "@/components/contracts/ContractApprovalStepsCard";
import { ContractClearanceReviewSection } from "@/components/contracts/ContractClearanceReviewSection";
import { ClearanceWorkflowFilesPanel } from "@/components/contracts/ClearanceWorkflowFilesPanel";
import { ContractRevisionTimeline } from "@/components/contracts/ContractRevisionTimeline";
import {
  ContractCustomerCard,
  ContractDocumentsCard,
} from "@/components/contracts/detail/ContractDetailTabCards";
import { getContractStatusMeta } from "@/features/contracts/contract-status.config";
import { useFileViewer } from "@/hooks/useFileViewer";
import {
  useContractDetail,
  useContractMutations,
} from "@/hooks/contracts/useContracts";
import { contractsService } from "@/services/contracts.service";
import { api } from "@/services/api";
import { QUERY_KEYS } from "@/constants/QUERY_KEYS";
import {
  downloadBookingFile,
  fetchViewableFile,
} from "@/services/files.service";
import type { CustomerDocument } from "@/types/customer";
import type { Freight } from "@edr/types";

// Clearance phase — staff can still ACT (approve / query / finalize).
const CLEARANCE_ACTIVE_STATUSES = [
  "AWAITING_CLEARANCE_DOCUMENTS",
  "CLEARANCE_UNDER_REVIEW",
  "CLEARANCE_READY_FOR_BOOKING",
];

// Clearance is done — the tab stays visible but READ-ONLY so staff/customer can
// see which documents were approved, by whom, and when.
const CLEARANCE_DONE_STATUSES = [
  "ACTIVE_SHIPMENT_IN_PROGRESS",
  "FULLY_EXECUTED",
  "CONTRACT_ACTIVE",
  "CONTRACT_CLOSED",
  "EXPIRED",
];

// Show the Clearance Review tab in either phase (active or done).
const CLEARANCE_REVIEW_STATUSES = [
  ...CLEARANCE_ACTIVE_STATUSES,
  ...CLEARANCE_DONE_STATUSES,
];

function formatDate(value: string | null | undefined): string {
  if (!value) return "—";
  const d = new Date(value);
  return Number.isNaN(d.getTime())
    ? "—"
    : d.toLocaleDateString(undefined, {
        year: "numeric",
        month: "short",
        day: "numeric",
      });
}

export default function ContractRequestDetailPage() {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const {
    data: contract,
    isLoading,
    isError,
    refetch,
    isFetching,
  } = useContractDetail(id);
  const mutations = useContractMutations(id ?? "");
  const [searchParams, setSearchParams] = useSearchParams();
  const { view, viewer } = useFileViewer();
  const requestedTab = searchParams.get("tab");
  const setTab = (tab: string) =>
    setSearchParams(
      (prev) => {
        const next = new URLSearchParams(prev);
        if (tab === "details") next.delete("tab");
        else next.set("tab", tab);
        return next;
      },
      { replace: true },
    );

  const handleViewFile = (file: NonNullable<Freight.IContract["files"]>[number]) =>
    view({
      name: file.name,
      url: file.signedUrl ?? file.url,
      mimeType: file.mimeType,
    });

  const handleDownloadFile = async (
    file: NonNullable<Freight.IContract["files"]>[number],
  ) => {
    try {
      await downloadBookingFile(file.id, file.name);
    } catch {
      toast.error("Could not download file.");
    }
  };

  const showClearanceTabQuery = Boolean(
    contract && CLEARANCE_REVIEW_STATUSES.includes(contract.status),
  );
  const { data: clearanceView } = useQuery({
    queryKey: QUERY_KEYS.CONTRACTS.clearance(id ?? ""),
    queryFn: () => contractsService.getClearance(id!),
    enabled: Boolean(id) && showClearanceTabQuery,
  });

  // Customer profile documents (national ID, TIN, import/business license) for
  // the company this contract belongs to. Shown as a separate section in the
  // Documents tab, alongside the contract's own attached files.
  const companyId = contract?.companyId ?? "";
  const profileDocumentsQuery = useQuery(
    api.customers.documents.queryOptions({
      input: { id: companyId },
      enabled: Boolean(companyId),
    }),
  );
  const profileDocumentsRaw = Array.isArray(profileDocumentsQuery.data)
    ? profileDocumentsQuery.data
    : [];
  // Reshape to the contract-file shape so we can reuse ContractDocumentsCard.
  const profileDocuments = profileDocumentsRaw.map(
    (doc: CustomerDocument) =>
      ({
        id: doc.id,
        code: doc.code,
        name: doc.name,
        url: doc.url ?? "",
        mimeType: doc.mimeType,
        size: doc.size,
        resourceId: companyId,
        resource: "company",
      }) satisfies NonNullable<Freight.IContract["files"]>[number],
  );

  const downloadContractPdf = async () => {
    if (!contract?.id) return;
    try {
      const blob = await contractsService.downloadContractDocument(contract.id);
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      const contractPdf = contract.files?.find((f) => f.code === "contract");
      a.download = contractPdf?.name ?? `contract-${contract.reference}.pdf`;
      a.click();
      URL.revokeObjectURL(url);
    } catch {
      toast.error("Could not download contract PDF.");
    }
  };

  if (isLoading) {
    return (
      <PageContainer>
        <Center mih="60vh">
          <Stack align="center" gap="md">
            <Loader color="gray" />
            <Text size="sm" c="dimmed" fw={500}>
              Loading contract…
            </Text>
          </Stack>
        </Center>
      </PageContainer>
    );
  }

  if (isError || !contract) {
    return (
      <PageContainer>
        <Container size="sm" py="xl">
          <Paper radius="md" withBorder p="xl" ta="center" style={detailStyles.card}>
            <Center>
              <Box
                style={{
                  display: "flex",
                  alignItems: "center",
                  justifyContent: "center",
                  width: 64,
                  height: 64,
                  borderRadius: 16,
                  background: "var(--mantine-color-gray-1)",
                  color: "var(--mantine-color-gray-6)",
                }}
              >
                <FileText size={32} />
              </Box>
            </Center>
            <Text fw={700} size="lg" mt="lg">
              Contract not found
            </Text>
            <Text size="sm" c="dimmed" mt={4}>
              This request may have been removed or the link is invalid.
            </Text>
            <Button
              variant="default"
              mt="lg"
              leftSection={<ArrowLeft size={16} />}
              onClick={() => navigate("/dashboard/contract-requests")}
            >
              Back to contract requests
            </Button>
          </Paper>
        </Container>
      </PageContainer>
    );
  }

  const statusMeta = getContractStatusMeta(contract.status);
  const routes = [...(contract.routes ?? [])].sort(
    (a, b) => a.sortOrder - b.sortOrder,
  );
  const showApprovalCard =
    contract.status === "PENDING_APPROVAL" ||
    contract.status === "APPROVED" ||
    contract.status === "APPROVED_PENDING_SIGNATURE" ||
    contract.status === "REJECTED";

  const showClearanceTab = CLEARANCE_REVIEW_STATUSES.includes(contract.status);
  const phasedCustoms =
    contract.contractKind === "ONE_TIME" && Boolean(contract.customsClearingEnabled);
  const docsPhaseComplete =
    clearanceView?.milestones?.some(
      (m) => m.milestoneCode === "DOCUMENTS_APPROVED" && m.status === "COMPLETED",
    ) ?? false;
  const clearanceApprovalsLocked = phasedCustoms && docsPhaseComplete;
  // Once clearance is finalized the tab is informational only — no approve/query.
  const clearanceReadOnly = CLEARANCE_DONE_STATUSES.includes(contract.status);
  // Path A (no customs) → Operations reviews; Path B (customs) → GL reviews.
  const selfClear = !contract.customsClearingEnabled;
  const files = contract.files ?? [];
  const contractPdf = files.find((f) => f.code === "contract");
  // Signature files (code `signature_<role>`) are baked into the contract PDF —
  // don't list them as standalone documents in the Documents tab.
  const contractDocuments = files.filter(
    (f) => !f.code.startsWith("signature_"),
  );
  const hasContractDocument = Boolean(
    contractPdf || contract.contractGeneratedAt,
  );
  const canViewSign =
    (contract.status === "CONTRACT_READY" ||
      contract.status === "SIGNED_CUSTOMER") &&
    Boolean(contract.contractGeneratedAt);
  // Resolve the active tab from the URL, falling back to details when the
  // requested tab isn't available for this contract (e.g. clearance pre-phase).
  const currentTab =
    requestedTab === "documents"
      ? "documents"
      : requestedTab === "customer"
        ? "customer"
        : requestedTab === "clearance" && showClearanceTab
          ? "clearance"
          : "details";

  const customerLabel = contract.isGovernment
    ? (contract.governmentInstitution ?? "Government")
    : (contract.company?.name ?? "—");

  return (
    <PageContainer>
      <Breadcrumbs
        items={[
          { label: "Contract requests", href: "/dashboard/contract-requests" },
          { label: contract.reference },
        ]}
      />

      <Stack gap="lg">
        {/* Hero */}
        <Paper radius="xl" p="xl" style={{ position: "relative", overflow: "hidden" }}>
          <Stack gap="lg">
            <Group justify="space-between" align="flex-start" wrap="wrap">
              <Button
                variant="default"
                size="compact-sm"
                radius="lg"
                leftSection={<ArrowLeft size={16} />}
                onClick={() => navigate("/dashboard/contract-requests")}
              >
                Back to list
              </Button>
              <Button
                variant="light"
                color="edr-green"
                size="compact-sm"
                radius="lg"
                leftSection={<RefreshCw size={15} />}
                loading={isFetching}
                onClick={() => refetch()}
              >
                Refresh
              </Button>
            </Group>

            <Stack gap="sm">
              <Text
                size="xs"
                fw={700}
                tt="uppercase"
                style={{ letterSpacing: 1, color: "#B26C09" }}
              >
                Contract reference
              </Text>
              <Group gap="sm" align="center" wrap="wrap">
                <Title order={2} fw={700} style={{ letterSpacing: "-0.4px" }}>
                  {contract.reference}
                </Title>
                <ContractStatusBadge
                  status={contract.status}
                  isRenewal={Boolean(contract.renewalOfId)}
                />
                <Badge variant="light" color="gray" radius="sm" tt="uppercase">
                  {contract.contractKind === "GENERAL" ? "General" : "One-time"}
                </Badge>
              </Group>
              <Group gap="lg" mt={4}>
                <MetaItem icon={Building2} text={customerLabel} />
                <MetaItem
                  icon={Calendar}
                  text={`Created ${formatDate(contract.createdAt)}`}
                />
                {contract.contractValidUntil ? (
                  <MetaItem
                    icon={CalendarClock}
                    text={`Valid until ${formatDate(contract.contractValidUntil)}`}
                  />
                ) : null}
              </Group>
              {hasContractDocument && (
                <Group gap="sm" mt="sm">
                  {canViewSign && (
                    <Button
                      color="edr-green"
                      size="compact-sm"
                      radius="lg"
                      leftSection={<FileSignature size={15} />}
                      onClick={() =>
                        navigate(`/dashboard/contract-requests/${contract.id}/view`)
                      }
                    >
                      View &amp; sign contract
                    </Button>
                  )}
                  {contractPdf && (
                    <Button
                      variant="default"
                      size="compact-sm"
                      radius="lg"
                      leftSection={<FileText size={15} />}
                      onClick={() =>
                        void fetchViewableFile(contractPdf.id, contractPdf.name).then(
                          view,
                        )
                      }
                    >
                      View contract
                    </Button>
                  )}
                  <Button
                    variant="default"
                    size="compact-sm"
                    radius="lg"
                    leftSection={<Download size={15} />}
                    onClick={() => void downloadContractPdf()}
                  >
                    Download PDF
                  </Button>
                </Group>
              )}
            </Stack>
          </Stack>
        </Paper>

        <ContractWorkflowStepper
          status={contract.status}
          title={statusMeta.title}
          description={statusMeta.description}
        />

        {contract.status === "REJECTED" && contract.latestRejectionNote ? (
          <Alert
            color="red"
            radius="md"
            icon={<AlertTriangle size={18} />}
            title="Rejection reason"
          >
            <Text size="sm" style={{ whiteSpace: "pre-wrap" }}>
              {contract.latestRejectionNote}
            </Text>
          </Alert>
        ) : null}

        {contract.status === "PENDING_APPROVAL" && contract.latestSendBackNote ? (
          <Alert
            color="orange"
            radius="md"
            icon={<AlertTriangle size={18} />}
            title="Sent back in the approval chain"
          >
            <Text size="sm" style={{ whiteSpace: "pre-wrap" }}>
              {contract.latestSendBackNote}
            </Text>
          </Alert>
        ) : null}

        <Tabs
          value={currentTab}
          onChange={(v) => setTab(v ?? "details")}
          variant="pills"
          color="edr-green"
          classNames={{ list: "ov-tablist", tab: "ov-tab" }}
        >
          <Tabs.List>
            <Tabs.Tab value="details" leftSection={<LayoutGrid size={16} />}>
              Details
            </Tabs.Tab>
            <Tabs.Tab
              value="documents"
              leftSection={<Files size={16} />}
              rightSection={
                contractDocuments.length + profileDocuments.length > 0 ? (
                  <Badge size="xs" variant="light" color="gray" radius="sm">
                    {contractDocuments.length + profileDocuments.length}
                  </Badge>
                ) : null
              }
            >
              Documents
            </Tabs.Tab>
            <Tabs.Tab value="customer" leftSection={<Users size={16} />}>
              Customer
            </Tabs.Tab>
            {showClearanceTab && (
              <Tabs.Tab
                value="clearance"
                leftSection={<ShieldCheck size={16} />}
              >
                Clearance Review
              </Tabs.Tab>
            )}
          </Tabs.List>
        </Tabs>

        <Grid gap="lg">
          {/* LEFT — primary content */}
          <Grid.Col span={{ base: 12, lg: 8 }}>
            {currentTab === "clearance" ? (
              <Stack gap="lg">
                <ContractClearanceReviewSection
                  contractId={id!}
                  selfClear={selfClear}
                  readOnly={clearanceReadOnly}
                  phasedCustoms={phasedCustoms}
                  approvalsLocked={clearanceApprovalsLocked}
                  onChanged={() => refetch()}
                />
                {(clearanceView?.workflowFiles?.length ?? 0) > 0 ? (
                  <ClearanceWorkflowFilesPanel
                    files={clearanceView!.workflowFiles!}
                    onView={view}
                    onDownload={(f) => void handleDownloadFile({ id: f.id, name: f.name } as never)}
                  />
                ) : null}
              </Stack>
            ) : currentTab === "documents" ? (
              <Stack gap="lg">
                <ContractDocumentsCard
                  files={contractDocuments}
                  onView={handleViewFile}
                  onDownload={handleDownloadFile}
                />
                <ContractRevisionTimeline contractId={contract.id} />
                <ContractDocumentsCard
                  files={profileDocuments}
                  title="Customer profile documents"
                  emptyText={
                    profileDocumentsQuery.isLoading
                      ? "Loading customer documents…"
                      : "No profile documents on file for this customer."
                  }
                  onView={handleViewFile}
                  onDownload={handleDownloadFile}
                />
                {(clearanceView?.workflowFiles?.length ?? 0) > 0 ? (
                  <ClearanceWorkflowFilesPanel
                    files={clearanceView!.workflowFiles!}
                    title="Customs workflow documents"
                    onView={view}
                    onDownload={(f) => void handleDownloadFile({ id: f.id, name: f.name } as never)}
                  />
                ) : null}
              </Stack>
            ) : currentTab === "customer" ? (
              <ContractCustomerCard contract={contract} />
            ) : (
            <Stack gap="lg">
              <SectionCard icon={RouteIcon} title="Routes">
                {routes.length === 0 ? (
                  <Text size="sm" c="dimmed">
                    No routes on this contract.
                  </Text>
                ) : (
                  <Stack gap="sm">
                    {routes.map((r) => (
                      <Group
                        key={r.id}
                        justify="space-between"
                        wrap="nowrap"
                        px="sm"
                        py="xs"
                        style={{
                          borderRadius: 8,
                          border: "1px solid var(--mantine-color-gray-2)",
                        }}
                      >
                        <Group gap={8} wrap="nowrap" style={{ minWidth: 0 }}>
                          <Text size="sm" fw={600} truncate maw={160}>
                            {r.originYard?.label ??
                              r.originYard?.code ??
                              "Origin"}
                          </Text>
                          <ArrowRight
                            size={15}
                            className="shrink-0 text-muted-foreground"
                          />
                          <Text size="sm" fw={600} truncate maw={160}>
                            {r.destinationYard?.label ??
                              r.destinationYard?.code ??
                              "Destination"}
                          </Text>
                        </Group>
                        {r.km != null ? (
                          <Badge variant="light" color="gray" radius="sm">
                            {r.km} km
                          </Badge>
                        ) : null}
                      </Group>
                    ))}
                  </Stack>
                )}
              </SectionCard>

              <SectionCard icon={Package} title="Cargo scope">
                <Group gap="sm" mb="md">
                  <Badge variant="light" color="gray" radius="sm" tt="uppercase">
                    {directionLabel(contract.tradeDirection)}
                  </Badge>
                  <Badge variant="light" color="gray" radius="sm" tt="uppercase">
                    {contract.freightType}
                  </Badge>
                  {contract.isHazardous ? (
                    <Badge
                      variant="light"
                      color="orange"
                      radius="sm"
                      leftSection={<Flame size={12} />}
                    >
                      Hazardous
                    </Badge>
                  ) : null}
                  {contract.isReefer ? (
                    <Badge
                      variant="light"
                      color="cyan"
                      radius="sm"
                      leftSection={<Snowflake size={12} />}
                    >
                      Reefer
                    </Badge>
                  ) : null}
                </Group>
                {(contract.cargoScope ?? []).length === 0 ? (
                  <Text size="sm" c="dimmed">
                    No cargo scope lines.
                  </Text>
                ) : (
                  <Stack gap="sm">
                    {(contract.cargoScope ?? []).map((s) => {
                      const isContainer = Boolean(s.containerSize);
                      // Bulk lines carry their commodity detail (name + unit);
                      // container lines carry the size (20ft / 40ft).
                      const title = isContainer
                        ? `${s.containerSize} container`
                        : (s.cargoType?.cargoTypeName ??
                          s.cargoFreeText ??
                          s.cargoType?.code ??
                          "Bulk cargo");
                      // quantityCap unit: containers for a size line, else the
                      // cargo type's unit of measure (tons / items / …), default tons.
                      const capUnit = isContainer
                        ? "containers"
                        : (s.cargoType?.unitOfMeasure?.toLowerCase() ?? "tons");
                      return (
                        <Group key={s.id} gap={8} wrap="nowrap" align="flex-start">
                          <BoxIcon
                            size={15}
                            color="var(--mantine-color-edr-green-6)"
                            style={{ marginTop: 2, flexShrink: 0 }}
                          />
                          <div>
                            <Text size="sm" fw={500}>
                              {title}
                            </Text>
                            <Group gap={6} mt={2}>
                              <Badge
                                variant="light"
                                color={isContainer ? "blue" : "grape"}
                                radius="sm"
                                size="xs"
                                tt="uppercase"
                              >
                                {isContainer ? "Container" : "Bulk"}
                              </Badge>
                              {s.cargoType?.code ? (
                                <Text size="xs" c="dimmed">
                                  Code: {s.cargoType.code}
                                </Text>
                              ) : null}
                              <Text size="xs" c="dimmed">
                                {s.quantityCap != null
                                  ? `Cap: ${s.quantityCap} ${capUnit}`
                                  : "Cap: uncapped"}
                              </Text>
                            </Group>
                          </div>
                        </Group>
                      );
                    })}
                  </Stack>
                )}
              </SectionCard>

              {contract.pricingBreakdown?.lineItems?.length ? (
                <SectionCard icon={Receipt} title="Unit rates">
                  <Stack gap="xs">
                    {contract.pricingBreakdown.lineItems.map((li) => (
                      <Group
                        key={li.code}
                        justify="space-between"
                        wrap="nowrap"
                      >
                        <Text size="sm" truncate>
                          {li.label}
                          {li.containerSize ? ` · ${li.containerSize}` : ""}
                        </Text>
                        <Text size="sm" fw={600}>
                          {contract.pricingBreakdown?.currency} {li.unitPrice} /{" "}
                          {li.unit}
                        </Text>
                      </Group>
                    ))}
                  </Stack>
                </SectionCard>
              ) : null}

              {contract.contractSummary ? (
                <SectionCard icon={FileText} title="Contract summary">
                  <Text size="sm" style={{ whiteSpace: "pre-wrap" }}>
                    {contract.contractSummary}
                  </Text>
                </SectionCard>
              ) : null}
            </Stack>
            )}
          </Grid.Col>

          {/* RIGHT — sticky action rail */}
          <Grid.Col span={{ base: 12, lg: 4 }}>
            <Box style={{ position: "sticky", top: 24 }}>
              <Stack gap="lg">
                <ContractActionsToolbar
                  contract={contract}
                  mutations={mutations}
                  onReviewClearance={
                    showClearanceTab ? () => setTab("clearance") : undefined
                  }
                />
                {showApprovalCard && (
                  <ContractApprovalStepsCard
                    contract={contract}
                    mutations={mutations}
                  />
                )}
              </Stack>
            </Box>
          </Grid.Col>
        </Grid>
      </Stack>

      {viewer}
    </PageContainer>
  );
}

function MetaItem({
  icon: Icon,
  text,
}: {
  icon: typeof Building2;
  text: string;
}) {
  return (
    <Group gap={6} wrap="nowrap">
      <Icon size={14} color="var(--mantine-color-gray-5)" />
      <Text size="sm" fw={600} c="dark">
        {text}
      </Text>
    </Group>
  );
}
