import { useMemo, useState } from "react";
import { Check, ShieldCheck } from "lucide-react";

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 { bookingGlass, bookingSurface } from "./booking-ui.styles";
import { Badge, Button } from "@edr/ui-common";
import { cn } from "@/lib/utils";

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() },
    );
  };

  return (
    <>
      <div className={cn(bookingSurface.sectionCard, bookingGlass.activeTab)}>
        <div className={bookingSurface.sectionHeader}>
          <div className={bookingSurface.sectionIcon}>
            <ShieldCheck className="size-4" strokeWidth={1.75} />
          </div>
          <div>
            <h2 className="text-sm font-semibold text-foreground">
              Approval chain
            </h2>
            <p className="text-xs text-muted-foreground">
              {summary.detail ||
                (nextPending
                  ? `Next: ${nextPending.requiredRole} · step ${nextPending.stepOrder}`
                  : steps.length
                    ? "All steps complete"
                    : "Accept submission to begin")}
            </p>
          </div>
        </div>

        <div className="px-5 py-5">
          {steps.length === 0 ? (
            <p className="rounded-lg border border-dashed border-border/60 bg-muted/10 px-4 py-6 text-center text-sm text-muted-foreground backdrop-blur-sm">
              Use{" "}
              <strong className="font-semibold text-foreground">
                Accept for approval
              </strong>{" "}
              in staff actions to instantiate steps.
            </p>
          ) : (
            <ul className="space-y-2">
              {steps.map((step) => (
                <StepRow
                  key={step.id}
                  step={step}
                  steps={steps}
                  user={user}
                  isNext={nextPending?.id === step.id}
                  isPending={mutations.approveStep.isPending}
                  onApprove={openApprove}
                />
              ))}
            </ul>
          )}
        </div>
      </div>

      <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 statusStyles =
    step.status === "APPROVED"
      ? "border-emerald-500/25 bg-emerald-500/10 text-black"
      : step.status === "REJECTED"
        ? "bg-red-500/10 text-red-800 dark:text-red-300"
        : isNext
          ? "border-emerald-500/25 bg-emerald-500/10 text-black"
          : "bg-muted/40 text-muted-foreground";

  return (
    <li
      className={cn(
        "flex items-center justify-between gap-3 rounded-lg border px-4 py-3 transition-colors backdrop-blur-sm",
        isNext ? bookingGlass.activeTab : "border-border/50 bg-card/60",
      )}
    >
      <div className="flex min-w-0 items-center gap-3">
        <span
          className={cn(
            "flex size-8 shrink-0 items-center justify-center rounded-lg text-xs font-bold",
            isNext
              ? cn(bookingGlass.iconWellGreen, "text-black")
              : "bg-muted/40 text-muted-foreground",
          )}
        >
          {step.stepOrder}
        </span>
        <div className="min-w-0">
          <p className="text-sm font-semibold text-foreground">
            {step.requiredRole}
          </p>
          {step.remarks && (
            <p className="truncate text-xs text-muted-foreground">
              {step.remarks}
            </p>
          )}
        </div>
      </div>
      <div className="flex shrink-0 items-center gap-2">
        {canApprove && (
          <Button
            type="button"
            size="sm"
            className="h-8 gap-1.5 shadow-sm"
            disabled={isPending}
            onClick={() => onApprove(step)}
          >
            <Check className="size-3.5" />
            Approve
          </Button>
        )}
        <Badge
          variant="outline"
          className={cn("shrink-0 border text-[9px] uppercase", statusStyles)}
        >
          {step.status}
        </Badge>
      </div>
    </li>
  );
}
