import { useMemo, useState } from "react";
import { useNavigate } from "react-router-dom";
import { useQuery } from "@tanstack/react-query";
import { Button, Modal, Stack, Text, Textarea } from "@mantine/core";
import {
  Check,
  Eye,
  FilePen,
  FileSignature,
  MessageSquareWarning,
  ShieldCheck,
  XCircle,
  Zap,
} from "lucide-react";
import type { Freight } from "@edr/types";

import { useAuth } from "@/auth/useAuth";
import { FREIGHT_PERMS, hasPermission } from "@/lib/permissions";
import { api } from "@/services/api";
import { contractsService } from "@/services/contracts.service";
import { SectionCard } from "@/components/bookings/detail/SectionCard";
import { ContractDocumentEditorModal } from "@/components/contracts/ContractDocumentEditorModal";
import { ContractPreviewModal } from "@/components/contracts/ContractPreviewModal";
import type { useContractMutations } from "@/hooks/contracts/useContracts";

/** Dropdown-settings code holding the admin-configured contract validity days. */
const CONTRACT_VALIDITY_PERIODS_CODE = "contract_validity_periods";

type Mutations = ReturnType<typeof useContractMutations>;

interface ContractActionsToolbarProps {
  contract: Freight.IContract;
  mutations: Mutations;
  /** Switch the detail page to its Clearance Review tab. */
  onReviewClearance?: () => void;
}

// Contract is in the pre-booking clearance phase — staff can review the
// customer's uploaded documents.
const CLEARANCE_REVIEW_STATUSES = [
  "AWAITING_CLEARANCE_DOCUMENTS",
  "CLEARANCE_UNDER_REVIEW",
  "CLEARANCE_READY_FOR_BOOKING",
];

/** Detail-page staff actions: accept / request changes / reject / generate / sign. */
export function ContractActionsToolbar({
  contract,
  mutations,
  onReviewClearance,
}: ContractActionsToolbarProps) {
  const navigate = useNavigate();
  const { user } = useAuth();
  const { status } = contract;

  // Intake permissions are split per freight type: an accept:bulk holder must
  // not see the accept button on a container contract (API enforces the same).
  const arm = contract.freightType === "BULK" ? "bulk" : "container";
  const mayAccept = hasPermission(user, FREIGHT_PERMS.contracts.staffAccept[arm]);
  const mayRequestChanges = hasPermission(
    user,
    FREIGHT_PERMS.contracts.requestChanges[arm],
  );
  const mayReject = hasPermission(user, FREIGHT_PERMS.contracts.reject[arm]);

  const [editorOpen, setEditorOpen] = useState(false);
  const [editorMode, setEditorMode] = useState<"accept" | "edit">("accept");
  const [previewOpen, setPreviewOpen] = useState(false);
  const [changesOpen, setChangesOpen] = useState(false);
  const [changesNote, setChangesNote] = useState("");
  const [rejectOpen, setRejectOpen] = useState(false);
  const [rejectReason, setRejectReason] = useState("");

  // Whether the document is editable depends on WHO is viewing — only the
  // approver whose turn it is may edit — so the server decides, not the client.
  const { data: draft } = useQuery({
    queryKey: ["contracts", contract.id, "document-draft"],
    queryFn: () => contractsService.getContractDocumentDraft(contract.id),
    enabled: contract.status === "PENDING_APPROVAL",
    staleTime: 0,
  });

  // Admin-configured validity durations (days) for the accept dialog. Staff can
  // only pick one of these — no free-typing. Read-only setting, fetched once.
  const { data: validitySetting, isLoading: validityLoading } = useQuery({
    ...api.dropdownSettings.getByCode.queryOptions({
      input: { code: CONTRACT_VALIDITY_PERIODS_CODE },
    }),
    retry: false,
  });
  const validityOptions = useMemo(
    () =>
      [...(validitySetting?.children ?? [])]
        .sort((a, b) => (a.order ?? 0) - (b.order ?? 0))
        .map((o) => ({ value: String(o.value), label: o.label })),
    [validitySetting],
  );

  if (["REJECTED", "CANCELLED", "EXPIRED", "CONTRACT_CLOSED"].includes(status)) {
    return null;
  }

  if (status === "CHANGES_REQUESTED") {
    return (
      <SectionCard icon={Zap} title="Awaiting customer">
        <Text size="sm" c="dimmed">
          No staff actions until the customer resubmits the contract.
        </Text>
      </SectionCard>
    );
  }

  const canAccept =
    status === "SUBMITTED" && (mayAccept || mayRequestChanges || mayReject);
  // The document stays editable for the whole approval chain, but only by the
  // approver whose turn it is. The server resolves that against the caller's
  // position type; the client cannot derive it.
  const canEditDocument = Boolean(draft?.editableByMe);
  const inApproval = status === "PENDING_APPROVAL";
  // Signing now happens on the contract VIEW page (staff must open and read the
  // generated contract before signing) — no sign button in this toolbar.
  const canViewContract =
    ["CONTRACT_READY", "SIGNED_CUSTOMER"].includes(status) &&
    Boolean(contract.contractGeneratedAt);
  // Show "Review clearance" while the contract is in the document-review phase.
  // Reviewer = GL (Path B / customs) or Operations (Path A / no customs).
  const canReviewClearance =
    Boolean(onReviewClearance) &&
    CLEARANCE_REVIEW_STATUSES.includes(status);
  const clearanceReviewer = contract.customsClearingEnabled
    ? "Review clearance (GL)"
    : "Review clearance (Ops)";

  return (
    <SectionCard icon={Zap} title="Staff actions">
      <Stack gap="sm">
        <Text size="xs" c="dimmed">
          Confirm each step before it is applied.
        </Text>

        {canAccept && (
          <>
            {mayAccept && (
              <Button
                fullWidth
                color="edr-green"
                leftSection={<Check size={16} />}
                onClick={() => {
                  setEditorMode("accept");
                  setEditorOpen(true);
                }}
              >
                Accept for approval
              </Button>
            )}
            {mayRequestChanges && (
              <Button
                fullWidth
                variant="light"
                color="orange"
                leftSection={<MessageSquareWarning size={16} />}
                onClick={() => setChangesOpen(true)}
              >
                Request changes
              </Button>
            )}
            {mayReject && (
              <Button
                fullWidth
                variant="light"
                color="red"
                leftSection={<XCircle size={16} />}
                onClick={() => setRejectOpen(true)}
              >
                Reject contract
              </Button>
            )}
          </>
        )}

        {inApproval && (
          <>
            <Text size="xs" c="dimmed">
              {canEditDocument
                ? "It is your turn to approve. You can edit the articles before approving — the PDF is generated automatically once the last approver approves."
                : draft?.nextApproverRole
                  ? `Awaiting ${draft.nextApproverRole}. Only the current approver can edit the document.`
                  : "Awaiting approval."}
            </Text>
            <Button
              fullWidth
              variant="light"
              color="gray"
              leftSection={<Eye size={16} />}
              onClick={() => setPreviewOpen(true)}
            >
              Preview document
            </Button>
            {canEditDocument && (
              <Button
                fullWidth
                variant="light"
                color="gray"
                leftSection={<FilePen size={16} />}
                onClick={() => {
                  setEditorMode("edit");
                  setEditorOpen(true);
                }}
              >
                Edit contract articles
              </Button>
            )}
          </>
        )}

        {canViewContract && (
          <Button
            fullWidth
            color="edr-green"
            leftSection={<FileSignature size={16} />}
            onClick={() =>
              navigate(`/dashboard/contract-requests/${contract.id}/view`)
            }
          >
            View &amp; sign contract
          </Button>
        )}

        {canReviewClearance && (
          <Button
            fullWidth
            color="edr-green"
            variant="light"
            leftSection={<ShieldCheck size={16} />}
            onClick={onReviewClearance}
          >
            {clearanceReviewer}
          </Button>
        )}

        {/* GL "Create booking" removed for now — clearance ends at finalize and
            the customer creates the booking in the portal. */}

        {!canAccept &&
          !inApproval &&
          !canViewContract &&
          !canReviewClearance && (
            <Text size="sm" c="dimmed">
              No staff actions available for this status. Monitor until the
              workflow advances.
            </Text>
          )}
      </Stack>

      {/* Accept / edit — review + optionally edit this contract's articles */}
      <ContractDocumentEditorModal
        opened={editorOpen}
        onClose={() => setEditorOpen(false)}
        contractId={contract.id}
        mode={editorMode}
        validityOptions={validityOptions}
        validityLoading={validityLoading}
        accepting={mutations.staffAccept.isPending}
        saving={mutations.updateDocument.isPending}
        onAccept={(days, snapshot, window) =>
          mutations.staffAccept.mutate(
            { validityDays: days, documentSnapshot: snapshot, ...window },
            { onSuccess: () => setEditorOpen(false) },
          )
        }
        onSaveEdit={(snapshot) =>
          mutations.updateDocument.mutate(snapshot, {
            onSuccess: () => setEditorOpen(false),
          })
        }
      />

      <ContractPreviewModal
        opened={previewOpen}
        onClose={() => setPreviewOpen(false)}
        contractId={contract.id}
      />

      {/* Request changes */}
      <Modal
        opened={changesOpen}
        onClose={() => setChangesOpen(false)}
        title="Request changes"
        centered
      >
        <Stack gap="md">
          <Textarea
            label="What needs to change?"
            placeholder="Describe the changes the customer must make…"
            autosize
            minRows={3}
            value={changesNote}
            onChange={(e) => setChangesNote(e.currentTarget.value)}
          />
          <Button
            color="orange"
            disabled={!changesNote.trim()}
            loading={mutations.requestChanges.isPending}
            onClick={() =>
              mutations.requestChanges.mutate(changesNote, {
                onSuccess: () => {
                  setChangesOpen(false);
                  setChangesNote("");
                },
              })
            }
          >
            Send to customer
          </Button>
        </Stack>
      </Modal>

      {/* Reject */}
      <Modal
        opened={rejectOpen}
        onClose={() => setRejectOpen(false)}
        title="Reject contract"
        centered
      >
        <Stack gap="md">
          <Textarea
            label="Reason for rejection"
            placeholder="Explain why this contract is rejected…"
            autosize
            minRows={3}
            value={rejectReason}
            onChange={(e) => setRejectReason(e.currentTarget.value)}
          />
          <Button
            color="red"
            disabled={!rejectReason.trim()}
            loading={mutations.reject.isPending}
            onClick={() =>
              mutations.reject.mutate(rejectReason, {
                onSuccess: () => {
                  setRejectOpen(false);
                  setRejectReason("");
                },
              })
            }
          >
            Reject
          </Button>
        </Stack>
      </Modal>
    </SectionCard>
  );
}
