import {
  Button,
  Group,
  Modal,
  Text,
  ThemeIcon,
  type ButtonProps,
} from "@mantine/core";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import type { LucideIcon } from "lucide-react";
import { useState, type ReactNode } from "react";
import toast from "react-hot-toast";
import { useNavigate } from "react-router-dom";

import type { Freight } from "@edr/types";

import { PayNowButton } from "@/pages/bookings/payments/PayNowButton";
import { api } from "@/services/api";
import { deriveContractCustomerAction } from "./deriveContractCustomerAction";

interface ContractCustomerActionProps {
  contract: Freight.IContract;
  bookings: Freight.IBooking[];
  size?: ButtonProps["size"];
  /** Extra props for list-row button styling (ContractsList). */
  listStyle?: boolean;
}

export function ContractCustomerAction({
  contract,
  bookings,
  size = "xs",
  listStyle = false,
}: ContractCustomerActionProps) {
  const navigate = useNavigate();
  const action = deriveContractCustomerAction(contract, bookings);

  const buttonStyles = listStyle
    ? {
        root: {
          fontWeight: 600,
          fontSize: 13,
          paddingInline: 14,
          whiteSpace: "nowrap" as const,
          boxShadow: action.primary
            ? "0 1px 2px rgba(14,163,113,0.25)"
            : "none",
        },
      }
    : undefined;

  if (action.type === "pay") {
    return (
      <PayNowButton booking={action.booking} label={action.label} size={size} />
    );
  }

  if (action.type === "initiate") {
    return (
      <InitiateBookingButton
        contract={action.contract}
        label={action.label}
        icon={action.icon}
        size={size}
        listStyle={listStyle}
      />
    );
  }

  const Icon = action.icon;
  const variant = action.primary ? "filled" : "light";

  return (
    <Button
      size={size}
      radius="md"
      h={listStyle ? 34 : undefined}
      variant={variant}
      color="edr-green"
      leftSection={<Icon size={15} />}
      onClick={(e) => {
        e.stopPropagation();
        navigate(action.to);
      }}
      styles={buttonStyles}
      fw={listStyle ? undefined : 700}
      fz={listStyle ? undefined : 13}
    >
      {action.label}
    </Button>
  );
}

/**
 * One-click bare booking instance under a self-clearance import/export contract
 * — ONE_TIME or GENERAL. No form, no date, no window gate: the new instance
 * lands in per-booking clearance (AWAITING_DOCUMENTS) with the customer on it.
 */
export function InitiateBookingButton({
  contract,
  label = "Initiate booking",
  icon: Icon,
  size = "xs",
  listStyle = false,
  fullWidth = false,
}: {
  contract: Freight.IContract;
  label?: string;
  icon: LucideIcon;
  size?: ButtonProps["size"];
  listStyle?: boolean;
  fullWidth?: boolean;
}) {
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const [confirmOpen, setConfirmOpen] = useState(false);

  const mutation = useMutation({
    mutationFn: () =>
      api.contracts.initiateBookingUnderContract.call({
        id: contract.id,
        // Multi-route contracts must name a route; single-route auto-selects.
        contractRouteId:
          (contract.routes?.length ?? 0) > 1
            ? contract.routes![0].id
            : undefined,
      }),
    onSuccess: (booking) => {
      queryClient.invalidateQueries({ queryKey: api.bookings.list.queryKey() });
      queryClient.invalidateQueries({
        queryKey: api.contracts.get.queryKey({ id: contract.id }),
      });
      toast.success(
        "Booking initiated — upload your clearance documents to start the review.",
      );
      setConfirmOpen(false);
      navigate(`/bookings/${booking.id}`);
    },
    onError: (e: Error) =>
      toast.error(e.message || "Could not initiate the booking"),
  });

  return (
    <>
      <Modal
        opened={confirmOpen}
        onClose={() => {
          if (!mutation.isPending) setConfirmOpen(false);
        }}
        centered
        radius="lg"
        size="md"
        closeOnClickOutside={!mutation.isPending}
        closeOnEscape={!mutation.isPending}
        withCloseButton={!mutation.isPending}
        title={
          <Group gap={10} wrap="nowrap">
            <ThemeIcon variant="light" color="edr-green" radius="md" size={34}>
              <Icon size={18} />
            </ThemeIcon>
            <Text fw={700}>Initiate a new booking?</Text>
          </Group>
        }
      >
        <Text size="sm" c="dimmed">
          This creates a new shipment booking under contract{" "}
          <Text span fw={700} c="#10202F">
            {contract.reference}
          </Text>
          . You&apos;ll upload the clearance documents next, and the shipment
          quantity is drawn down from your contract&apos;s reserved capacity.
        </Text>
        <Group justify="flex-end" gap="sm" mt="lg">
          <Button
            variant="default"
            radius="md"
            onClick={() => setConfirmOpen(false)}
            disabled={mutation.isPending}
          >
            Cancel
          </Button>
          <Button
            color="edr-green"
            radius="md"
            leftSection={<Icon size={16} />}
            loading={mutation.isPending}
            onClick={() => mutation.mutate()}
          >
            Yes, initiate booking
          </Button>
        </Group>
      </Modal>
      <Button
        size={size}
        radius="md"
        h={listStyle ? 34 : undefined}
        variant="filled"
        color="edr-green"
        fullWidth={fullWidth}
        leftSection={<Icon size={15} />}
        loading={mutation.isPending}
        onClick={(e) => {
          e.stopPropagation();
          setConfirmOpen(true);
        }}
        styles={
          listStyle
            ? {
                root: {
                  fontWeight: 600,
                  fontSize: 13,
                  paddingInline: 14,
                  whiteSpace: "nowrap" as const,
                  boxShadow: "0 1px 2px rgba(14,163,113,0.25)",
                },
              }
            : undefined
        }
        fw={listStyle ? undefined : 700}
        fz={listStyle ? undefined : 13}
      >
        {label}
      </Button>
    </>
  );
}

/** Action column cell: doc button + primary customer action. */
export function ContractCustomerActionCell({
  contract,
  bookings,
  docButton,
}: {
  contract: Freight.IContract;
  bookings: Freight.IBooking[];
  docButton: ReactNode;
}) {
  return (
    <Group gap={8} wrap="nowrap" justify="flex-end">
      {docButton}
      <ContractCustomerAction
        contract={contract}
        bookings={bookings}
        size="sm"
        listStyle
      />
    </Group>
  );
}
