import { useCallback, useState } from "react";

import {
  getBookingActions,
  type BookingActionContext,
  type BookingActionDef,
} from "@/features/bookings/booking-actions.config";
import { useAuth } from "@/auth/useAuth";
import { useBookingMutations } from "@/hooks/bookings/useBookings";

/** A contract validity window must be a whole number of days, 1–365. */
function isValidValidityDays(value: string): boolean {
  const days = Number(value.trim());
  return Number.isInteger(days) && days >= 1 && days <= 365;
}

export function useBookingActionDialog(
  bookingId: string,
  context: BookingActionContext,
) {
  const [pendingAction, setPendingAction] = useState<BookingActionDef | null>(null);
  const [inputValue, setInputValue] = useState("");
  const [selectedFile, setSelectedFile] = useState<File | null>(null);
  const [dialogOpen, setDialogOpen] = useState(false);

  // Bookings no longer have an approval chain, so the dialog needs nothing
  // beyond the list-row context it was handed.
  const detailLoading = false;

  const mergedContext: BookingActionContext = { ...context };

  const { user } = useAuth();
  const mutations = useBookingMutations(bookingId);
  const actions = getBookingActions(mergedContext, user);

  const openAction = useCallback((action: BookingActionDef) => {
    setPendingAction(action);
    setInputValue("");
    setSelectedFile(null);
    setDialogOpen(true);
  }, []);

  const closeDialog = useCallback(() => {
    setDialogOpen(false);
    setPendingAction(null);
    setInputValue("");
    setSelectedFile(null);
  }, []);

  const runAction = useCallback(() => {
    if (!pendingAction) return;

    const onSuccess = () => closeDialog();

    switch (pendingAction.id) {
      case "accept": {
        const days = Number(inputValue.trim());
        if (!Number.isInteger(days) || days < 1 || days > 365) return;
        mutations.staffAccept.mutate(days, { onSuccess });
        break;
      }
      case "requestChanges":
        mutations.requestChanges.mutate(inputValue.trim(), { onSuccess });
        break;
      case "reject":
        mutations.staffReject.mutate(inputValue.trim(), { onSuccess });
        break;
      case "operationAccept":
        mutations.reviewOperation.mutate({ decision: "ACCEPT" }, { onSuccess });
        break;
      case "operationRequestChanges":
        mutations.reviewOperation.mutate(
          { decision: "REQUEST_CHANGES", note: inputValue.trim() },
          { onSuccess },
        );
        break;
      case "viewContract":
        break;
      case "startTransit":
        mutations.startTransit.mutate(undefined, { onSuccess });
        break;
      case "complete":
        mutations.complete.mutate(undefined, { onSuccess });
        break;
      case "cancel":
        mutations.cancel.mutate(inputValue.trim(), { onSuccess });
        break;
      default:
        break;
    }
  }, [
    pendingAction,
    inputValue,
    selectedFile,
    mutations,
    closeDialog,
  ]);

  const confirmDisabled =
    mutations.isPending ||
    (pendingAction?.input === "file" && !selectedFile) ||
    (pendingAction?.input === "reason" && !inputValue.trim()) ||
    (pendingAction?.input === "note" && !inputValue.trim()) ||
    (pendingAction?.input === "days" && !isValidValidityDays(inputValue));

  return {
    actions,
    pendingAction,
    inputValue,
    setInputValue,
    selectedFile,
    setSelectedFile,
    dialogOpen,
    setDialogOpen: (open: boolean) => {
      if (!open) closeDialog();
      else setDialogOpen(true);
    },
    openAction,
    closeDialog,
    runAction,
    mutations,
    confirmDisabled,
    detailLoading,
    mergedContext,
  };
}
