"use client";

import { useState, useCallback, useMemo } from "react";

interface CanSubmitDependencies {
  /** Whether payment methods are still loading */
  paymentMethodsLoading: boolean;
  /** Whether user has at least one payment method */
  hasPaymentMethod: boolean;
  /** Whether residence card has been submitted (pending or verified) */
  residenceSubmitted: boolean;
  /** Eligibility state */
  eligibility: {
    isLoading: boolean;
    isPending: boolean;
    isNotRequested: boolean;
    isIneligible: boolean;
    isError: boolean;
    isEligible: boolean;
  };
}

/**
 * Hook that consolidates checkout form state.
 * Manages submission state, address confirmation, errors, and portal opening state.
 */
export function useCheckoutFormState() {
  const [submitting, setSubmitting] = useState(false);
  const [addressConfirmed, setAddressConfirmed] = useState(false);
  const [submitError, setSubmitError] = useState<string | null>(null);
  const [openingPaymentPortal, setOpeningPaymentPortal] = useState(false);

  const confirmAddress = useCallback(() => {
    setAddressConfirmed(true);
  }, []);

  const unconfirmAddress = useCallback(() => {
    setAddressConfirmed(false);
  }, []);

  const startSubmitting = useCallback(() => {
    setSubmitError(null);
    setSubmitting(true);
  }, []);

  const stopSubmitting = useCallback(() => {
    setSubmitting(false);
  }, []);

  const setError = useCallback((error: string | null) => {
    setSubmitError(error);
  }, []);

  const startOpeningPortal = useCallback(() => {
    setOpeningPaymentPortal(true);
  }, []);

  const stopOpeningPortal = useCallback(() => {
    setOpeningPaymentPortal(false);
  }, []);

  /**
   * Computes whether the form can be submitted based on all dependencies.
   */
  const computeCanSubmit = useCallback((deps: CanSubmitDependencies) => {
    return (
      deps.eligibility.isEligible &&
      !deps.paymentMethodsLoading &&
      deps.hasPaymentMethod &&
      deps.residenceSubmitted &&
      !deps.eligibility.isLoading &&
      !deps.eligibility.isPending &&
      !deps.eligibility.isNotRequested &&
      !deps.eligibility.isIneligible &&
      !deps.eligibility.isError
    );
  }, []);

  return {
    /** Form state values */
    formState: {
      submitting,
      addressConfirmed,
      submitError,
      openingPaymentPortal,
    },
    /** Address confirmation handlers */
    confirmAddress,
    unconfirmAddress,
    /** Submission state handlers */
    startSubmitting,
    stopSubmitting,
    setError,
    /** Payment portal state handlers */
    startOpeningPortal,
    stopOpeningPortal,
    /** Compute if form can be submitted */
    computeCanSubmit,
  };
}

/**
 * Hook that provides a memoized canSubmit value given dependencies.
 * Use this when you want to reactively compute canSubmit based on changing dependencies.
 */
export function useCanSubmit(
  addressConfirmed: boolean,
  deps: Omit<CanSubmitDependencies, "addressConfirmed"> & { addressConfirmed?: never }
) {
  return useMemo(
    () =>
      addressConfirmed &&
      deps.eligibility.isEligible &&
      !deps.paymentMethodsLoading &&
      deps.hasPaymentMethod &&
      deps.residenceSubmitted &&
      !deps.eligibility.isLoading &&
      !deps.eligibility.isPending &&
      !deps.eligibility.isNotRequested &&
      !deps.eligibility.isIneligible &&
      !deps.eligibility.isError,
    [
      addressConfirmed,
      deps.eligibility.isEligible,
      deps.eligibility.isLoading,
      deps.eligibility.isPending,
      deps.eligibility.isNotRequested,
      deps.eligibility.isIneligible,
      deps.eligibility.isError,
      deps.paymentMethodsLoading,
      deps.hasPaymentMethod,
      deps.residenceSubmitted,
    ]
  );
}
