import { useMemo, useState } from "react";
import { useNavigate } from "react-router-dom";
import { useMutation, useQueries, useQuery } from "@tanstack/react-query";
import { Badge, Box, Button, Group, Modal, Stack, Text } from "@mantine/core";
import {
  AlertTriangle,
  CreditCard,
  FilePlus2,
  FileSignature,
  PackagePlus,
  Receipt,
  Upload,
} from "lucide-react";
import type { Freight } from "@edr/types";

import { api } from "@/services/api";
import { ModalSafeWrapper } from "@/components/customer-actions/ModalSafeWrapper";
import { paymentsService, type PaymentMethod } from "@/services/payments.service";
import { invoicesService } from "@/services/invoices.service";
import { isPayable } from "@/pages/billing/invoice-ui";
import { ContractClearancePanel } from "@/pages/contracts/ContractClearancePanel";
import { PaymentMethodModal } from "@/pages/bookings/BookingDetailPage/components/PaymentMethodModal";
import { Card } from "./Card";
import type { ActionItem } from "../actions";

// Contracts whose clearance is still in progress — candidates for a real
// per-document query check (small set; only contracts awaiting/under review).
const CLEARANCE_CANDIDATE_STATUSES = [
  "AWAITING_CLEARANCE_DOCUMENTS",
  "CLEARANCE_UNDER_REVIEW",
];

const KIND_META: Record<
  ActionItem["kind"],
  { icon: typeof Upload; label: string; color: string }
> = {
  clearance: { icon: Upload, label: "Clearance", color: "edr-green" },
  duty: { icon: Receipt, label: "Duty / tax", color: "orange" },
  sign: { icon: FileSignature, label: "Sign", color: "blue" },
  book: { icon: PackagePlus, label: "Book", color: "violet" },
  pay: { icon: CreditCard, label: "Payment", color: "orange" },
};

export interface ActionNeededSectionProps {
  /** Non-clearance actions (sign / book / pay) derived from status. */
  items: ActionItem[];
  /** All of the customer's contracts — used to detect real clearance queries. */
  contracts: Freight.IContract[];
}

/**
 * Home "needs your attention" card. Lists pending customer actions across
 * contracts and bookings. Clearance items are derived from the ACTUAL clearance
 * documents (so an open query always surfaces an upload button), payment + the
 * clearance upload open in a modal right here; sign and book navigate.
 */
export function ActionNeededSection({
  items: baseItems,
  contracts,
}: ActionNeededSectionProps) {
  const navigate = useNavigate();
  const [clearanceId, setClearanceId] = useState<string | null>(null);
  const [payItem, setPayItem] = useState<ActionItem | null>(null);

  // Fetch the clearance view for every contract still in a clearance phase, so we
  // can detect a queried document precisely (status alone can be ambiguous).
  const candidates = useMemo(
    () =>
      contracts.filter((c) =>
        CLEARANCE_CANDIDATE_STATUSES.includes(c.status),
      ),
    [contracts],
  );

  const clearanceQueries = useQueries({
    queries: candidates.map((c) =>
      api.contracts.getClearance.queryOptions({ input: { id: c.id } }),
    ),
  });

  // Build clearance action items from the fetched views: show whenever the
  // customer can still upload (not yet ready for booking), flag urgent + show the
  // query count when any document was sent back for correction.
  const clearanceItems = useMemo<ActionItem[]>(() => {
    const out: ActionItem[] = [];
    candidates.forEach((c, i) => {
      const view = clearanceQueries[i]?.data;
      const docs = view?.documents ?? [];
      const customerDocs = docs.filter((d) => d.uploadedBy === "customer");
      const queried = customerDocs.filter(
        (d) => d.reviewStatus === "QUERIED",
      ).length;
      const ready =
        view?.clearanceStatus === "CLEARANCE_READY_FOR_BOOKING" ||
        view?.clearanceStatus === "SELF_CLEARED" ||
        view?.clearanceStatus === "ACTIVE_SHIPMENT_IN_PROGRESS";
      if (ready) return;
      const awaiting =
        c.status === "AWAITING_CLEARANCE_DOCUMENTS" ||
        view?.clearanceStatus === "AWAITING_DOCUMENTS";
      // Duty phase: the customer's task is paying duty/tax and uploading the
      // slip — a distinct, money action, not a generic document upload.
      if (view?.phase === "CUSTOMER_DUTY") {
        out.push({
          id: `duty-${c.id}`,
          kind: "duty",
          reference: c.reference,
          description: "Duty / tax payment due — pay and upload the slip",
          targetId: c.id,
          urgent: true,
        });
        return;
      }
      // Only surface when there's something the customer can do: a query, or the
      // contract is awaiting their (re)upload.
      if (queried === 0 && !awaiting) return;
      out.push({
        id: `clearance-${c.id}`,
        kind: "clearance",
        reference: c.reference,
        description:
          queried > 0
            ? `${queried} document${queried > 1 ? "s" : ""} need correction`
            : "Clearance documents needed",
        targetId: c.id,
        urgent: queried > 0 || awaiting,
      });
    });
    return out;
  }, [candidates, clearanceQueries]);

  // Merge: clearance items (from real docs) + the status-derived sign/book/pay.
  const items = useMemo(
    () => [...clearanceItems, ...baseItems.filter((i) => i.kind !== "clearance")],
    [clearanceItems, baseItems],
  ).sort((a, b) => Number(b.urgent ?? 0) - Number(a.urgent ?? 0));

  // Billing is invoice-centric — resolve the booking's currently payable
  // invoice before paying it (mirrors ReadonlyBookingView).
  const { data: payItemInvoices = [] } = useQuery({
    queryKey: ["booking-invoices", payItem?.targetId],
    queryFn: () =>
      invoicesService.listForSource("booking", payItem!.targetId),
    enabled: payItem !== null,
  });
  const payableInvoiceId = payItemInvoices.find((inv) =>
    isPayable(inv.status),
  )?.id;

  const payMutation = useMutation({
    mutationFn: (method: PaymentMethod) => {
      if (!payableInvoiceId) {
        throw new Error(
          "No payable invoice found for this booking yet. Please refresh or contact support.",
        );
      }
      return api.invoices.pay.call({
        id: payableInvoiceId,
        payload: { method, platform: "web" },
      });
    },
    onSuccess: (data, method) => {
      const url =
        data?.clientAction?.type === "REDIRECT" && data.clientAction.url
          ? data.clientAction.url
          : paymentsService.checkoutUrlForInvoice({
              invoiceId: payableInvoiceId!,
              method,
            });
      window.location.href = url;
    },
  });

  if (items.length === 0) return null;

  const handleClick = (item: ActionItem) => {
    switch (item.kind) {
      case "clearance":
        setClearanceId(item.targetId);
        break;
      case "duty":
        // Duty advice + payment-slip upload live on the contract detail page.
        navigate(`/contracts/${item.targetId}`);
        break;
      case "pay":
        setPayItem(item);
        break;
      case "sign":
        navigate(`/contracts/${item.targetId}/view`);
        break;
      case "book":
        navigate(`/contracts/${item.targetId}/bookings/new`);
        break;
    }
  };

  return (
    <Card padding={0}>
      <Group justify="space-between" align="center" px={24} pt={20} pb={12}>
        <Group gap={8}>
          <AlertTriangle size={18} className="text-amber-500" />
          <Text fw={700} fz={16} c="edr-text">
            Needs your attention
          </Text>
        </Group>
        <Badge color="orange" variant="light" radius="sm">
          {items.length}
        </Badge>
      </Group>

      <Stack gap={0}>
        {items.map((item, i) => {
          const meta = KIND_META[item.kind];
          const Icon = meta.icon;
          return (
            <Group
              key={item.id}
              justify="space-between"
              wrap="nowrap"
              px={24}
              py={14}
              style={{
                borderTop:
                  i === 0
                    ? "none"
                    : "1px solid var(--mantine-color-gray-2)",
                cursor: "pointer",
              }}
              onClick={() => handleClick(item)}
              className="hover:bg-edr-soft"
            >
              <Group gap={12} wrap="nowrap" style={{ minWidth: 0 }}>
                <Box
                  style={{
                    width: 36,
                    height: 36,
                    flexShrink: 0,
                    borderRadius: 10,
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "center",
                    background: `var(--mantine-color-${meta.color}-light)`,
                    color: `var(--mantine-color-${meta.color}-filled)`,
                  }}
                >
                  <Icon size={18} />
                </Box>
                <Box style={{ minWidth: 0 }}>
                  <Group gap={8} wrap="nowrap">
                    <Text fw={600} fz={14} c="edr-text" truncate>
                      {item.reference}
                    </Text>
                    {item.urgent && (
                      <Badge size="xs" color="red" variant="light" radius="sm">
                        Action required
                      </Badge>
                    )}
                  </Group>
                  <Text fz={12.5} c="dimmed" truncate>
                    {item.description}
                  </Text>
                </Box>
              </Group>
              <Button
                size="compact-sm"
                variant={item.urgent ? "filled" : "light"}
                color={meta.color}
                radius="md"
                leftSection={
                  item.kind === "clearance" ? (
                    <Upload size={14} />
                  ) : item.kind === "duty" ? (
                    <Receipt size={14} />
                  ) : (
                    <FilePlus2 size={14} />
                  )
                }
              >
                {item.kind === "pay"
                  ? "Pay now"
                  : item.kind === "duty"
                    ? "Pay duty & upload slip"
                    : item.kind === "sign"
                      ? "Sign"
                      : item.kind === "book"
                        ? "Book"
                        : item.urgent
                          ? "Upload documents"
                          : "Upload"}
              </Button>
            </Group>
          );
        })}
      </Stack>

      <ModalSafeWrapper>
        <Modal
          opened={clearanceId !== null}
          onClose={() => setClearanceId(null)}
          title={
            <Text fw={700} fz={16}>
              Clearance documents
            </Text>
          }
          size="xl"
          radius="md"
          centered
          overlayProps={{ blur: 2, backgroundOpacity: 0.55 }}
        >
          {clearanceId && (
            <ContractClearancePanel contractId={clearanceId} bare />
          )}
        </Modal>

        <PaymentMethodModal
          opened={payItem !== null}
          onClose={() => {
            if (!payMutation.isPending) {
              setPayItem(null);
              payMutation.reset();
            }
          }}
          currency={undefined}
          processing={payMutation.isPending}
          error={
            payMutation.isError
              ? payMutation.error instanceof Error
                ? payMutation.error.message
                : "Could not start payment. Please try again."
              : null
          }
          onConfirm={(method) => payMutation.mutate(method)}
        />
      </ModalSafeWrapper>
    </Card>
  );
}
