import { useMemo, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { useQuery } from "@tanstack/react-query";
import {
  Badge,
  Box,
  Button,
  Card,
  Center,
  Group,
  Loader,
  Paper,
  Progress,
  RingProgress,
  Stack,
  Text,
  ThemeIcon,
  Title,
} from "@mantine/core";
import {
  ArrowLeft,
  CalendarClock,
  Inbox,
  Layers,
  MapPin,
  PackageCheck,
  PackagePlus,
  Ship,
} from "lucide-react";

import { api } from "@/services/api";
import { PayNowButton } from "../bookings/payments/PayNowButton";
import {
  BORDER,
  ContractStatusBadge,
  formatQuantity,
  GREEN,
  INK,
  MetaItem,
  MUTED,
  StatCard,
} from "./contract-ui";
import { PlaceOrderDialog } from "./PlaceOrderDialog";

export default function ContractDetailPage() {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const [orderOpen, setOrderOpen] = useState(false);

  const {
    data: contract,
    isLoading,
    isError,
  } = useQuery(api.bookings.get.queryOptions({ input: { id: id! }, enabled: !!id }));

  const { data: pool } = useQuery({
    ...api.bookingOrders.pool.queryOptions({
      input: { contractBookingId: id! },
    }),
    enabled: !!id && contract?.status !== "DRAFT",
  });

  const { data: orders } = useQuery({
    ...api.bookingOrders.listByContract.queryOptions({
      input: { contractBookingId: id! },
    }),
    enabled: !!id && contract?.status !== "DRAFT",
  });

  if (isLoading) {
    return (
      <Center mih={400} p="xl">
        <Stack align="center" gap="md">
          <Loader color="edr-green" />
          <Text size="sm" c="dimmed">
            Loading contract…
          </Text>
        </Stack>
      </Center>
    );
  }

  if (isError || !contract) {
    return (
      <Box p="xl">
        <Paper withBorder radius="lg" p="xl" style={{ borderColor: BORDER }}>
          <Text fw={700} mb="xs">
            Contract not found
          </Text>
          <Button variant="default" onClick={() => navigate("/contracts")}>
            Back to contracts
          </Button>
        </Paper>
      </Box>
    );
  }

  const isContainer = contract.freightType === "CONTAINER";
  const isActive = contract.status === "CONTRACT_ACTIVE";
  const awaitingPayment = contract.status === "FULLY_EXECUTED";
  const poolLines = pool ?? [];
  const showPool = contract.status !== "DRAFT";

  // Overall utilization across every pool line — drives the header ring + stat.
  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]);

  return (
    <Box style={{ padding: "28px 32px 40px" }}>
      <Stack gap="lg">
        {/* Header */}
        <Group justify="space-between" align="flex-start" wrap="wrap" gap="md">
          <Group gap="md" align="center" wrap="nowrap">
            <Button
              variant="subtle"
              color="gray"
              radius="md"
              px={8}
              onClick={() => navigate("/contracts")}
            >
              <ArrowLeft size={18} />
            </Button>
            <Group gap={12} wrap="nowrap" align="center">
              <ThemeIcon size={48} radius="lg" variant="light" color="violet">
                <Layers size={23} />
              </ThemeIcon>
              <div>
                <Group gap={10} align="center">
                  <Title order={2} fw={800} fz={22} style={{ color: INK }}>
                    {contract.reference}
                  </Title>
                  <ContractStatusBadge status={contract.status} />
                </Group>
                <Text size="sm" c="dimmed" mt={2}>
                  General contract · {isContainer ? "Containerised" : "Bulk"} ·{" "}
                  {contract.tradeDirection ?? "—"}
                </Text>
              </div>
            </Group>
          </Group>

          <Group gap="sm">
            {awaitingPayment && (
              <PayNowButton booking={contract} label="Pay & activate" size="sm" />
            )}
            {isActive && (
              <Button
                color="edr-green"
                radius="md"
                size="md"
                leftSection={<PackagePlus size={16} />}
                onClick={() => setOrderOpen(true)}
              >
                Place order
              </Button>
            )}
          </Group>
        </Group>

        {/* Summary meta */}
        <Paper withBorder radius="lg" p="lg" style={{ borderColor: BORDER }}>
          <Group gap={48} wrap="wrap">
            <MetaItem
              label="Route"
              icon={<MapPin size={15} color={MUTED} />}
              value={`${contract.originYard?.label ?? "—"} → ${contract.destinationYard?.label ?? "—"}`}
            />
            <MetaItem
              label="Ordering until"
              icon={<CalendarClock size={15} color={MUTED} />}
              value={
                contract.expiresAt
                  ? new Date(contract.expiresAt).toLocaleDateString()
                  : "Not active yet"
              }
            />
            <MetaItem
              label="Trade direction"
              icon={<Ship size={15} color={MUTED} />}
              value={contract.tradeDirection ?? "—"}
            />
          </Group>
        </Paper>

        {/* Stat strip */}
        {showPool && (
          <Group gap="md" wrap="wrap" align="stretch">
            <StatCard
              label="Orders placed"
              value={orders?.length ?? 0}
              icon={PackageCheck}
              color="violet"
            />
            <StatCard
              label="Utilization"
              hint="of reserved quantity"
              value={`${totals.pct}%`}
              icon={PackageCheck}
              color="edr-green"
            />
            <StatCard
              label="Ordering until"
              value={
                contract.expiresAt
                  ? new Date(contract.expiresAt).toLocaleDateString()
                  : "—"
              }
              icon={CalendarClock}
              color="edr-accent"
            />
          </Group>
        )}

        {/* Drawdown pool */}
        {showPool && (
          <Card withBorder radius="lg" p="lg" style={{ borderColor: BORDER }}>
            <Group justify="space-between" align="flex-start" wrap="nowrap" mb="lg">
              <Box>
                <Text fw={700} fz={16} style={{ color: INK }}>
                  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} style={{ color: INK }}>
                      {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} style={{ color: INK }}>
                          {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}
                          style={{ color: depleted ? MUTED : 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="lg" p="lg" style={{ borderColor: BORDER }}>
          <Group justify="space-between" align="center" mb="md">
            <Text fw={700} fz={16} style={{ color: INK }}>
              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}>
                {isActive
                  ? "No orders yet. Use “Place order” to draw down from this contract."
                  : "Orders can be placed once the contract is active (paid)."}
              </Text>
            </Stack>
          ) : (
            <Stack gap={10}>
              {orders.map((order) => (
                <Group
                  key={order.id}
                  justify="space-between"
                  wrap="nowrap"
                  p="sm"
                  style={{
                    borderRadius: 12,
                    border: `1px solid ${BORDER}`,
                  }}
                >
                  <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} style={{ color: INK }} truncate>
                        {order.reference}
                      </Text>
                      <Text fz={12} c="dimmed" truncate>
                        Ship {new Date(order.scheduledDate).toLocaleDateString()}
                        {" · "}
                        {order.lines
                          .map(
                            (l) =>
                              `${Number.isInteger(l.quantity) ? l.quantity : l.quantity.toFixed(2)}${
                                l.containerTypeName
                                  ? ` ${l.containerTypeName}`
                                  : ""
                              }`,
                          )
                          .join(", ")}
                      </Text>
                    </Box>
                  </Group>
                  <ContractStatusBadge status={order.status} />
                </Group>
              ))}
            </Stack>
          )}
        </Card>
      </Stack>

      <PlaceOrderDialog
        opened={orderOpen}
        onClose={() => setOrderOpen(false)}
        contract={contract}
        pool={poolLines}
        onPlaced={() => setOrderOpen(false)}
      />
    </Box>
  );
}
