import { useMemo, useState } from "react";
import { Check, ShieldCheck } from "lucide-react";
import { Stack, Group, Text, Badge, Button, Box } from "@mantine/core";

import { BookingConfirmDialog } from "./BookingConfirmDialog";
import { useAuth } from "@/auth/useAuth";
import { formatApprovalProgress } from "@/features/bookings/approval-progress";
import {
  buildApproveActionForStep,
  canActOnApprovalStep,
  getNextPendingApprovalStep,
} from "@/features/bookings/booking-actions.config";
import type { useBookingMutations } from "@/hooks/bookings/useBookings";
import type { BookingApprovalStep, BookingDetail } from "@/types/booking";
import { SectionCard } from "./detail/SectionCard";

type Mutations = ReturnType<typeof useBookingMutations>;

interface ApprovalStepsCardProps {
  booking: BookingDetail;
  mutations: Mutations;
}

/** Approval chain with inline approve on the current pending step. */
export function ApprovalStepsCard({ booking, mutations }: ApprovalStepsCardProps) {
  const { user } = useAuth();
  const [confirmOpen, setConfirmOpen] = useState(false);
  const [pendingStep, setPendingStep] = useState<BookingApprovalStep | null>(null);

  const steps = useMemo(
    () => [...(booking.approvalSteps ?? [])].sort((a, b) => a.stepOrder - b.stepOrder),
    [booking.approvalSteps],
  );

  const nextPending = getNextPendingApprovalStep(steps);
  const summary = formatApprovalProgress(booking.status, steps);
  const pendingAction = pendingStep ? buildApproveActionForStep(pendingStep) : null;

  const openApprove = (step: BookingApprovalStep) => {
    setPendingStep(step);
    setConfirmOpen(true);
  };

  const closeApprove = () => {
    setConfirmOpen(false);
    setPendingStep(null);
  };

  const runApprove = () => {
    if (!pendingStep) return;
    mutations.approveStep.mutate(
      { stepId: pendingStep.id, requiredRole: pendingStep.requiredRole },
      { onSuccess: () => closeApprove() },
    );
  };

  const subtitle =
    summary.detail ||
    (nextPending
      ? `Next: ${nextPending.requiredRole} · step ${nextPending.stepOrder}`
      : steps.length
        ? "All steps complete"
        : "Accept submission to begin");

  return (
    <>
      <SectionCard
        icon={ShieldCheck}
        title="Approval chain"
        extra={
          <Badge color="edr-green" variant="light" radius="sm">
            {steps.filter((s) => s.status === "APPROVED").length}/{steps.length}
          </Badge>
        }
      >
        <Text size="xs" c="dimmed" mb="sm">
          {subtitle}
        </Text>

        {steps.length === 0 ? (
          <Text
            size="sm"
            c="dimmed"
            ta="center"
            py="lg"
            px="md"
            style={{
              borderRadius: 8,
              border: "1px dashed var(--mantine-color-gray-3)",
              background: "var(--mantine-color-gray-0)",
            }}
          >
            Use <strong>Accept for approval</strong> in staff actions to instantiate steps.
          </Text>
        ) : (
          <Stack gap="xs">
            {steps.map((step) => (
              <StepRow
                key={step.id}
                step={step}
                steps={steps}
                user={user}
                isNext={nextPending?.id === step.id}
                isPending={mutations.approveStep.isPending}
                onApprove={openApprove}
              />
            ))}
          </Stack>
        )}
      </SectionCard>

      <BookingConfirmDialog
        open={confirmOpen}
        onOpenChange={(open) => {
          if (!open) closeApprove();
          else setConfirmOpen(true);
        }}
        action={pendingAction}
        reference={booking.reference}
        inputValue=""
        onInputChange={() => {}}
        onConfirm={runApprove}
        isPending={mutations.approveStep.isPending}
      />
    </>
  );
}

function StepRow({
  step,
  steps,
  user,
  isNext,
  isPending,
  onApprove,
}: {
  step: BookingApprovalStep;
  steps: BookingApprovalStep[];
  user: ReturnType<typeof useAuth>["user"];
  isNext: boolean;
  isPending: boolean;
  onApprove: (step: BookingApprovalStep) => void;
}) {
  const canApprove = canActOnApprovalStep(user, step, steps);
  const statusColor =
    step.status === "APPROVED"
      ? "edr-green"
      : step.status === "REJECTED"
        ? "red"
        : isNext
          ? "edr-green"
          : "gray";

  return (
    <Group
      justify="space-between"
      wrap="nowrap"
      gap="sm"
      px="sm"
      py="xs"
      style={{
        borderRadius: 8,
        border: "1px solid var(--mantine-color-gray-2)",
        borderLeft: isNext
          ? "3px solid var(--freight-brand)"
          : "1px solid var(--mantine-color-gray-2)",
        background: isNext ? "var(--mantine-color-gray-0)" : "white",
      }}
    >
      <Group gap="sm" wrap="nowrap" style={{ minWidth: 0 }}>
        <Box
          style={{
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            width: 28,
            height: 28,
            borderRadius: 8,
            flexShrink: 0,
            fontSize: 12,
            fontWeight: 700,
            background: "var(--mantine-color-gray-1)",
            color: isNext ? "var(--mantine-color-gray-7)" : "var(--mantine-color-gray-6)",
          }}
        >
          {step.stepOrder}
        </Box>
        <Box style={{ minWidth: 0 }}>
          <Text size="sm" fw={600}>
            {step.requiredRole}
          </Text>
          {step.remarks && (
            <Text size="xs" c="dimmed" truncate>
              {step.remarks}
            </Text>
          )}
        </Box>
      </Group>
      <Group gap="xs" wrap="nowrap" style={{ flexShrink: 0 }}>
        {canApprove && (
          <Button
            size="compact-sm"
            color="edr-green"
            leftSection={<Check size={14} />}
            disabled={isPending}
            onClick={() => onApprove(step)}
          >
            Approve
          </Button>
        )}
        <Badge variant="light" color={statusColor} size="sm" radius="sm" tt="uppercase">
          {step.status}
        </Badge>
      </Group>
    </Group>
  );
}
