import { Controller, type UseFormReturn } from "react-hook-form";
import {
  Badge,
  Box,
  Button,
  Group,
  Paper,
  Stack,
  Table,
  Text,
  Textarea,
} from "@mantine/core";
import { format } from "date-fns";
import {
  Calendar,
  CheckCircle2,
  Circle,
  ClipboardCheck,
  FileText,
  Package,
  Pencil,
  Route,
  Send,
  Truck,
} from "lucide-react";
import type { Freight } from "@/types";
import {
  type BookingFormInputValues,
  type BookingFormValues,
} from "./schema";
import { StepHeader } from "./shared";

export const REVIEW_STEP_TARGETS = {
  contract: 1,
  service: 2,
  cargo: 3,
  route: 4,
  schedule: 5,
  documents: 6,
} as const;

type BookingForm = UseFormReturn<
  BookingFormInputValues,
  any,
  BookingFormValues
>;

function OverviewSection({
  icon,
  title,
  onEdit,
  children,
}: {
  icon: React.ReactNode;
  title: string;
  onEdit: () => void;
  children: React.ReactNode;
}) {
  return (
    <Paper radius={16} p="lg" withBorder className="border-gray-200 bg-white">
      <Group justify="space-between" align="flex-start" mb="md" wrap="nowrap">
        <Group gap="sm" wrap="nowrap">
          <Box
            className="flex items-center justify-center rounded-lg"
            style={{
              width: 36,
              height: 36,
              backgroundColor: "var(--mantine-color-edr-green-0)",
              color: "var(--mantine-color-edr-green-7)",
            }}
          >
            {icon}
          </Box>
          <Text fw={700} size="sm" c="#10202F">
            {title}
          </Text>
        </Group>
        <Button
          type="button"
          variant="subtle"
          color="edr-green"
          size="compact-xs"
          leftSection={<Pencil size={13} />}
          onClick={onEdit}
        >
          Edit
        </Button>
      </Group>
      {children}
    </Paper>
  );
}

function DetailRow({ label, value }: { label: string; value: string }) {
  return (
    <Group justify="space-between" align="flex-start" wrap="nowrap" py={4}>
      <Text size="xs" c="dimmed" fw={600} tt="uppercase" className="tracking-wide">
        {label}
      </Text>
      <Text size="sm" fw={500} ta="right" maw="60%">
        {value || "—"}
      </Text>
    </Group>
  );
}

function ReadinessItem({
  done,
  label,
}: {
  done: boolean;
  label: string;
}) {
  return (
    <Group gap="sm" wrap="nowrap">
      {done ? (
        <CheckCircle2 size={18} className="shrink-0 text-emerald-600" />
      ) : (
        <Circle size={18} className="shrink-0 text-gray-300" />
      )}
      <Text size="sm" c={done ? "dark" : "dimmed"}>
        {label}
      </Text>
    </Group>
  );
}

export function Step8Review({
  form,
  setStep,
  direction,
  referenceData,
  onboardingDocs = [],
  onSaveDraft,
  onSubmit,
  saveDraftPending = false,
  submitPending = false,
}: {
  form: BookingForm;
  setStep: (step: number) => void;
  direction: Freight.ScheduleTradeDirection;
  referenceData?: Freight.BookingReferenceData;
  onboardingDocs?: Array<{ name: string; size?: number }>;
  onSaveDraft?: () => void;
  onSubmit?: () => void;
  saveDraftPending?: boolean;
  submitPending?: boolean;
}) {
  const values = form.watch();
  const serviceType = referenceData?.service.find(
    (s) => s.id === values.serviceTypeId,
  );

  const containerSummary =
    values.cargoType === "container" && values.containers.length > 0
      ? values.containers
          .filter((c) => +c.qty > 0)
          .map((c) => `${c.qty} × ${c.containerType || c.type}`)
          .join(", ")
      : "";

  // For bulk general contracts the quantity is reserved per route (the primary
  // route's amount lives in primaryRouteQuantity); one-time bookings use the
  // cargo-step cargoWeight.
  const isGeneralContract = values.bookingType === "general_contract";
  const bulkAmount =
    isGeneralContract && values.cargoType === "bulk"
      ? Number(values.primaryRouteQuantity || 0)
      : Number(values.cargoWeight || 0);
  const totalVgm =
    values.cargoType === "container"
      ? values.containers.reduce(
          (sum, c) => sum + (+c.qty || 0) * (+(c.vgm ?? 0) || 0),
          0,
        )
      : bulkAmount;

  // Documents are reused from onboarding (read-only) and attached on submit.
  const onboardingDocsCount = onboardingDocs.length;

  const selectedCommodity = (() => {
    if (values.cargoType !== "bulk" || !referenceData) return null;
    const path = values.cargoTypePath ?? [];
    const group = referenceData.cargo_type.find((g) => g.id === path[0]);
    return group?.children?.find((c) => c.id === path[1]) ?? null;
  })();

  const cargoValue = (() => {
    if (values.cargoType === "container") return "Container freight";
    if (!referenceData) return "";
    const path = values.cargoTypePath ?? [];
    const group = referenceData.cargo_type.find((g) => g.id === path[0]);
    if (!group) return "";
    const child = group.children?.find((c) => c.id === path[1]);
    return child ? `${group.name} — ${child.name}` : group.name;
  })();

  // Bulk PER_ITEM cargo is a whole item count, not tons — label it accordingly.
  const isPerItem = selectedCommodity?.unit_of_measure === "PER_ITEM";
  const totalQuantityRow = isPerItem
    ? {
        label: "Total quantity",
        value: totalVgm > 0 ? `${Math.round(totalVgm)} items` : "—",
      }
    : {
        label: "Total VGM",
        value: totalVgm > 0 ? `${totalVgm.toFixed(1)} tons` : "—",
      };

  const originYardName =
    referenceData?.yard.find((y) => y.id === values.originYard)?.name ??
    values.originYard;

  const destinationYardName =
    referenceData?.yard.find((y) => y.id === values.destinationYard)?.name ??
    values.destinationYard;

  const scheduleLabel = values.scheduledDate
    ? format(new Date(values.scheduledDate), "EEEE, MMM d, yyyy")
    : "—";

  const directionLabel = direction
    ? direction.charAt(0) + direction.slice(1).toLowerCase()
    : "—";

  return (
    <Stack gap="lg">
      <StepHeader
        icon={<ClipboardCheck size={22} />}
        title="Review & Submit"
        description="Review your booking overview before sending it for EDR staff review."
      />

      <div className="flex flex-col gap-6 lg:flex-row lg:items-start">
        {/* Left — booking summary */}
        <Stack gap="md" className="min-w-0 flex-1">
          <Paper
            radius={20}
            p="lg"
            className="border border-emerald-100 bg-gradient-to-br from-white to-emerald-50/40"
          >
            <Group justify="space-between" align="flex-start" wrap="wrap" gap="md">
              <Stack gap={4}>
                <Text size="xs" fw={700} tt="uppercase" c="edr-green" className="tracking-wider">
                  Booking overview
                </Text>
                <Text fw={800} size="xl" c="#10202F">
                  {values.contractType === "new" ? "New Contract" : "Contract Renewal"}
                </Text>
                <Text size="sm" c="dimmed">
                  {serviceType?.name ?? "—"} · {originYardName} → {destinationYardName}
                </Text>
              </Stack>
              <Badge size="lg" variant="light" color="edr-green" radius="md">
                {directionLabel}
              </Badge>
            </Group>
          </Paper>

          <OverviewSection
            icon={<Package size={18} />}
            title="Contract & Service"
            onEdit={() => setStep(REVIEW_STEP_TARGETS.contract)}
          >
            <DetailRow
              label="Contract"
              value={values.contractType === "new" ? "New Contract" : "Renewal"}
            />
            {values.contractType === "renewal" && values.previousContractRef && (
              <DetailRow label="Previous ref" value={values.previousContractRef} />
            )}
            <DetailRow label="Service" value={serviceType?.name ?? ""} />
            <DetailRow
              label="Payment currency"
              value={values.paymentCurrency ?? "USD"}
            />
            <Button
              type="button"
              variant="subtle"
              size="compact-xs"
              color="gray"
              mt={4}
              onClick={() => setStep(REVIEW_STEP_TARGETS.service)}
            >
              Edit service options
            </Button>
          </OverviewSection>

          <OverviewSection
            icon={<Route size={18} />}
            title="Route"
            onEdit={() => setStep(REVIEW_STEP_TARGETS.route)}
          >
            <DetailRow
              label="Corridor"
              value={`${originYardName} → ${destinationYardName}`}
            />
            <DetailRow label="Trade direction" value={directionLabel} />
            <DetailRow
              label="Modifiers"
              value={
                [values.isHazardous && "Hazardous", values.isRefrigerated && "Refrigerated"]
                  .filter(Boolean)
                  .join(", ") || "None"
              }
            />
          </OverviewSection>

          <OverviewSection
            icon={<Truck size={18} />}
            title="Logistics"
            onEdit={() => setStep(REVIEW_STEP_TARGETS.service)}
          >
            <DetailRow
              label="First mile"
              value={
                values.firstMile.enabled
                  ? values.firstMile.pickUpAddress
                  : "Not requested"
              }
            />
            <DetailRow
              label="Last mile"
              value={
                values.lastMile.enabled
                  ? values.lastMile.deliveryAddress
                  : "Not requested"
              }
            />
            <DetailRow
              label="Equipment return"
              value={
                values.equipmentReturn === "with_return"
                  ? "With return"
                  : "Without return"
              }
            />
            <DetailRow
              label="Customs clearing"
              value={
                values.customsClearingEnabled
                  ? values.customsClearingAgent
                    ? `Enabled — agent: ${values.customsClearingAgent}`
                    : "Enabled"
                  : "Not requested"
              }
            />
          </OverviewSection>

          <OverviewSection
            icon={<Calendar size={18} />}
            title="Schedule"
            onEdit={() => setStep(REVIEW_STEP_TARGETS.schedule)}
          >
            <DetailRow label="Estimated shipment date" value={scheduleLabel} />
          </OverviewSection>

          <OverviewSection
            icon={<Package size={18} />}
            title="Cargo"
            onEdit={() => setStep(REVIEW_STEP_TARGETS.cargo)}
          >
            <DetailRow label="Freight type" value={cargoValue} />
            {/* Containers carry no weight at the wizard — only bulk shows a quantity row. */}
            {values.cargoType === "bulk" && (
              <DetailRow
                label={totalQuantityRow.label}
                value={totalQuantityRow.value}
              />
            )}
            {values.cargoType === "container" && values.containers.length > 0 && (
              <Table mt="sm" withTableBorder withColumnBorders fz="sm">
                <Table.Thead>
                  <Table.Tr>
                    <Table.Th>Type</Table.Th>
                    <Table.Th>Qty</Table.Th>
                  </Table.Tr>
                </Table.Thead>
                <Table.Tbody>
                  {values.containers
                    .filter((c) => +c.qty > 0)
                    .map((c, i) => (
                      <Table.Tr key={i}>
                        <Table.Td>{c.containerType || c.type}</Table.Td>
                        <Table.Td>{c.qty}</Table.Td>
                      </Table.Tr>
                    ))}
                </Table.Tbody>
              </Table>
            )}
            {containerSummary && (
              <DetailRow label="Summary" value={containerSummary} />
            )}
          </OverviewSection>

          <OverviewSection
            icon={<FileText size={18} />}
            title="Documents"
            onEdit={() => setStep(REVIEW_STEP_TARGETS.documents)}
          >
            <Stack gap="xs">
              {onboardingDocsCount > 0 ? (
                onboardingDocs.map((doc, i) => (
                  <Group
                    key={`${doc.name}-${i}`}
                    justify="space-between"
                    wrap="nowrap"
                  >
                    <Group gap="xs" wrap="nowrap">
                      <CheckCircle2 size={16} className="text-emerald-600 shrink-0" />
                      <Text size="sm" className="truncate max-w-[60%]">
                        {doc.name}
                      </Text>
                    </Group>
                    <Text size="xs" c="dimmed">
                      Uploaded
                    </Text>
                  </Group>
                ))
              ) : (
                <Group gap="xs" wrap="nowrap">
                  <Circle size={16} className="text-gray-300 shrink-0" />
                  <Text size="sm" c="dimmed">
                    No onboarding documents found on your active profile.
                  </Text>
                </Group>
              )}
            </Stack>
            <Text size="xs" c="dimmed" mt="sm">
              Documents from your onboarding will be attached to this booking.
            </Text>
          </OverviewSection>

          <Controller
            name="notes"
            control={form.control}
            render={({ field }) => (
              <Textarea
                {...field}
                label="Additional notes"
                placeholder="Any special instructions for EDR operations…"
                rows={3}
                radius="md"
              />
            )}
          />
        </Stack>

        {/* Right — sticky actions */}
        <Box className="w-full shrink-0 lg:w-[340px] lg:sticky lg:top-24">
          <Stack gap="md">
            <Paper radius={20} p="lg" withBorder bg="white">
              <Text fw={800} size="sm" mb="md" c="#10202F">
                Submission readiness
              </Text>
              <Stack gap="sm">
                <ReadinessItem done={Boolean(values.serviceTypeId)} label="Service configured" />
                <ReadinessItem
                  done={Boolean(values.paymentCurrency)}
                  label="Payment currency selected"
                />
                <ReadinessItem
                  done={Boolean(values.originYard && values.destinationYard)}
                  label="Route selected"
                />
                <ReadinessItem
                  done={Boolean(values.scheduledDate)}
                  label="Shipment day selected"
                />
                <ReadinessItem
                  done={
                    values.cargoType === "container"
                      ? values.containers.some((c) => +c.qty > 0)
                      : bulkAmount > 0
                  }
                  label="Cargo details complete"
                />
                <ReadinessItem
                  done={onboardingDocsCount > 0}
                  label="Onboarding documents attached"
                />
              </Stack>
            </Paper>

            <Paper radius={20} p="lg" withBorder bg="white">
              <Text size="sm" c="dimmed" mb="md">
                Ready to submit. You'll review the unit rates before final
                submission.
              </Text>
              <Stack gap="sm">
                <Button
                  type="button"
                  color="edr-green"
                  radius="md"
                  fullWidth
                  size="md"
                  leftSection={<Send size={16} />}
                  onClick={onSubmit}
                  loading={submitPending}
                  disabled={submitPending}
                >
                  Submit
                </Button>
                <Button
                  type="button"
                  variant="outline"
                  color="edr-green"
                  radius="md"
                  fullWidth
                  onClick={onSaveDraft}
                  loading={saveDraftPending}
                  disabled={submitPending}
                >
                  Save as draft
                </Button>
              </Stack>
            </Paper>
          </Stack>
        </Box>
      </div>
    </Stack>
  );
}
