import { useRecoilCallback } from 'recoil';

import { billingCheckoutSessionState } from '@/auth/states/billingCheckoutSessionState';
import { BillingCheckoutSession } from '@/auth/types/billingCheckoutSession.type';
import { BILLING_CHECKOUT_SESSION_DEFAULT_VALUE } from '@/billing/constants/BillingCheckoutSessionDefaultValue';
import deepEqual from 'deep-equal';

// Initialize state that are hydrated from query parameters
// We used to use recoil-sync to do this, but it was causing issues with Firefox
export const useInitializeQueryParamState = () => {
  const initializeQueryParamState = useRecoilCallback(
    ({ set, snapshot }) =>
      () => {
        const handlers = {
          billingCheckoutSession: (value: string) => {
            const billingCheckoutSession = snapshot
              .getLoadable(billingCheckoutSessionState)
              .getValue();

            try {
              const parsedValue = JSON.parse(decodeURIComponent(value));

              if (
                typeof parsedValue === 'object' &&
                parsedValue !== null &&
                'plan' in parsedValue &&
                'interval' in parsedValue &&
                'requirePaymentMethod' in parsedValue &&
                !deepEqual(billingCheckoutSession, parsedValue)
              ) {
                set(
                  billingCheckoutSessionState,
                  parsedValue as BillingCheckoutSession,
                );
              }
            } catch (error) {
              // eslint-disable-next-line no-console
              console.error(
                'Failed to parse billingCheckoutSession from URL',
                error,
              );
              set(
                billingCheckoutSessionState,
                BILLING_CHECKOUT_SESSION_DEFAULT_VALUE,
              );
            }
          },
        };

        const queryParams = new URLSearchParams(window.location.search);

        for (const [paramName, handler] of Object.entries(handlers)) {
          const value = queryParams.get(paramName);
          if (value !== null) {
            handler(value);
          }
        }
      },
    [],
  );

  return { initializeQueryParamState };
};
