import { useMemo } from "react";
import { useNavigate } from "react-router-dom";
import {
  Badge,
  Box,
  Card,
  Center,
  Group,
  Loader,
  Progress,
  RingProgress,
  Stack,
  Text,
  ThemeIcon,
} from "@mantine/core";
import { ChevronRight, Inbox, PackageCheck } from "lucide-react";

import { BookingStatusBadge } from "@/components/bookings/BookingStatusBadge";
import {
  useContractOrders,
  useContractPool,
} from "@/hooks/bookings/useContractOrders";
import type { Freight } from "@edr/types";

export interface ContractOrdersPanelProps {
  /** The general-contract booking whose drawdown orders are listed. */
  contractBookingId: string;
  /** Whether the contract is container-based (affects quantity labels). */
  isContainer: boolean;
}

/** Format a contracted/remaining quantity with its unit. */
function formatQuantity(
  qty: number,
  unit: Freight.ContractQuantityLine["unitOfMeasure"],
  isContainerLine: boolean,
): string {
  const rounded = Number.isInteger(qty) ? qty : Number(qty.toFixed(2));
  if (isContainerLine) return `${rounded} containers`;
  if (unit === "PER_ITEM") return `${rounded} items`;
  return `${rounded} tons`;
}

/** Summarise an order's lines, e.g. "2 20FT, 1 40FT" or "15". */
function summariseLines(lines: Freight.IBookingOrderLine[]): string {
  return lines
    .map((l) => {
      const qty = Number(l.quantity);
      const label = Number.isInteger(qty) ? `${qty}` : qty.toFixed(2);
      return `${label}${l.containerTypeName ? ` ${l.containerTypeName}` : ""}`;
    })
    .join(", ");
}

/**
 * Backoffice "Orders" tab for a general contract: shows the drawdown pool and
 * lists each order placed against the contract. Each order links to its child
 * booking's detail page, where staff approve it and review clearance/customer
 * documents independently (same screen as a one-time booking).
 */
export function ContractOrdersPanel({
  contractBookingId,
  isContainer,
}: ContractOrdersPanelProps) {
  const navigate = useNavigate();
  const { data: orders, isLoading: ordersLoading } =
    useContractOrders(contractBookingId);
  const { data: pool, isLoading: poolLoading } =
    useContractPool(contractBookingId);

  const poolLines = pool ?? [];

  const totals = useMemo(() => {
    const contracted = poolLines.reduce(
      (s, l) => s + (l.contractedQuantity || 0),
      0,
    );
    const ordered = poolLines.reduce((s, l) => s + (l.orderedQuantity || 0), 0);
    const pct = contracted > 0 ? Math.round((ordered / contracted) * 100) : 0;
    return { contracted, ordered, pct };
  }, [poolLines]);

  if (ordersLoading || poolLoading) {
    return (
      <Center mih={240}>
        <Loader color="gray" />
      </Center>
    );
  }

  return (
    <Stack gap="lg">
      {/* Drawdown pool */}
      <Card withBorder radius="md" p="lg">
        <Group justify="space-between" align="flex-start" wrap="nowrap" mb="lg">
          <Box>
            <Text fw={700} fz={16}>
              Contracted quantity
            </Text>
            <Text fz={13} c="dimmed" mt={2}>
              How much of this contract has been ordered versus what remains.
            </Text>
          </Box>
          {totals.contracted > 0 && (
            <RingProgress
              size={72}
              thickness={7}
              roundCaps
              sections={[{ value: totals.pct, color: "edr-green" }]}
              label={
                <Text ta="center" fz={13} fw={800}>
                  {totals.pct}%
                </Text>
              }
            />
          )}
        </Group>
        <Stack gap="lg">
          {poolLines.length === 0 && (
            <Text fz={13} c="dimmed">
              No quantity pool available.
            </Text>
          )}
          {poolLines.map((line, i) => {
            const pct =
              line.contractedQuantity > 0
                ? Math.min(
                    100,
                    (line.orderedQuantity / line.contractedQuantity) * 100,
                  )
                : 0;
            const label = isContainer
              ? (line.containerTypeName ?? "Containers")
              : line.unitOfMeasure === "PER_ITEM"
                ? "Items"
                : "Tons";
            const depleted = line.remainingQuantity <= 0;
            return (
              <div key={line.containerTypeId ?? `bulk-${i}`}>
                <Group justify="space-between" mb={6}>
                  <Group gap={8} align="center">
                    <Text fz={14} fw={600}>
                      {label}
                    </Text>
                    {depleted && (
                      <Badge size="xs" variant="light" color="gray" radius="sm">
                        Fully ordered
                      </Badge>
                    )}
                  </Group>
                  <Text fz={13} c="dimmed">
                    <Text span fw={700} c={depleted ? "dimmed" : "edr-green"}>
                      {formatQuantity(
                        line.remainingQuantity,
                        line.unitOfMeasure,
                        isContainer,
                      )}
                    </Text>{" "}
                    remaining of{" "}
                    {formatQuantity(
                      line.contractedQuantity,
                      line.unitOfMeasure,
                      isContainer,
                    )}
                  </Text>
                </Group>
                <Progress
                  value={pct}
                  color={depleted ? "gray" : "edr-green"}
                  size="md"
                  radius="xl"
                />
              </div>
            );
          })}
        </Stack>
      </Card>

      {/* Orders */}
      <Card withBorder radius="md" p="lg">
        <Group justify="space-between" align="center" mb="md">
          <Text fw={700} fz={16}>
            Orders
          </Text>
          <Badge variant="light" color="violet" radius="sm">
            {orders?.length ?? 0}
          </Badge>
        </Group>
        {!orders || orders.length === 0 ? (
          <Stack align="center" gap={8} py="xl">
            <ThemeIcon size={48} radius="xl" variant="light" color="gray">
              <Inbox size={22} />
            </ThemeIcon>
            <Text fz={13} c="dimmed" ta="center" maw={360}>
              No orders have been placed against this contract yet.
            </Text>
          </Stack>
        ) : (
          <Stack gap={10}>
            {orders.map((order) => {
              const childId = order.bookingId;
              const clickable = Boolean(childId);
              return (
                <Group
                  key={order.id}
                  justify="space-between"
                  wrap="nowrap"
                  p="sm"
                  style={{
                    borderRadius: 12,
                    border: "1px solid var(--mantine-color-gray-3)",
                    cursor: clickable ? "pointer" : "default",
                  }}
                  onClick={
                    clickable
                      ? () =>
                          navigate(`/dashboard/booking-requests/${childId}`)
                      : undefined
                  }
                >
                  <Group gap={12} wrap="nowrap" style={{ minWidth: 0 }}>
                    <ThemeIcon
                      size={38}
                      radius="md"
                      variant="light"
                      color="violet"
                    >
                      <PackageCheck size={18} />
                    </ThemeIcon>
                    <Box style={{ minWidth: 0 }}>
                      <Text fz={14} fw={700} truncate>
                        {order.reference}
                      </Text>
                      <Text fz={12} c="dimmed" truncate>
                        Ship{" "}
                        {new Date(order.scheduledDate).toLocaleDateString()}
                        {order.lines.length > 0
                          ? ` · ${summariseLines(order.lines)}`
                          : ""}
                      </Text>
                    </Box>
                  </Group>
                  <Group gap={8} wrap="nowrap">
                    <BookingStatusBadge status={order.status} />
                    {clickable && (
                      <ChevronRight
                        size={16}
                        color="var(--mantine-color-gray-5)"
                      />
                    )}
                  </Group>
                </Group>
              );
            })}
          </Stack>
        )}
      </Card>
    </Stack>
  );
}
