"use client";

import { useCallback, useMemo } from "react";
import { useRouter } from "next/navigation";

import {
  behaviorAnalytics,
  getDefaultPaymentAnalyticsContext,
} from "@/lib/analytics";
import { getDefaultPayChannelForCountryCode } from "@/lib/payment/default_pay_channel";
import { useAuthSelector } from "@/stores/auth/auth-context";
import { useUserSelector } from "@/stores/user/user-context";

import {
  isAuthenticatedUser as resolveIsAuthenticatedUser,
  resolveAuthenticatedNavigation,
} from "./navigation-resolver";
import type { OpenSubscriptionInput } from "./navigation-types";
import { ROUTE_BUILDERS } from "./routes";

export interface OpenGlobalSubscriptionInput extends OpenSubscriptionInput {
  sourceCharacterSlug: string;
}

export interface GlobalAppNavigator {
  push: (href: string, options?: { scroll?: boolean }) => void;
  replace: (href: string, options?: { scroll?: boolean }) => void;
  back: () => void;
  openAuth: (redirectTo: string) => void;
  openSubscription: (input: OpenGlobalSubscriptionInput) => void;
  getDefaultPayChannel: () => ReturnType<
    typeof getDefaultPayChannelForCountryCode
  >;
  isAuthenticatedUser: boolean;
}

export function useGlobalAppNavigator(): GlobalAppNavigator {
  const router = useRouter();
  const loginStatus = useAuthSelector((state) => state.context.loginStatus);
  const countryCode = useUserSelector(
    (state) => state.context.currentUser?.countryCode,
  );
  const isAuthenticatedUser = resolveIsAuthenticatedUser(loginStatus);

  const push = useCallback(
    (href: string, options?: { scroll?: boolean }): void => {
      router.push(href, options);
    },
    [router],
  );

  const replace = useCallback(
    (href: string, options?: { scroll?: boolean }): void => {
      router.replace(href, options);
    },
    [router],
  );

  const back = useCallback((): void => {
    router.back();
  }, [router]);

  const openAuth = useCallback(
    (redirectTo: string): void => {
      router.push(ROUTE_BUILDERS.authWithRedirect(redirectTo));
    },
    [router],
  );

  const getDefaultPayChannel = useCallback(() => {
    return getDefaultPayChannelForCountryCode(countryCode);
  }, [countryCode]);

  const openSubscription = useCallback(
    ({
      type,
      sourceCharacterSlug,
      payChannel = getDefaultPayChannel(),
      returnTo = null,
      replace: shouldReplace = false,
      analytics = getDefaultPaymentAnalyticsContext(type),
      chatActionId,
      planId,
      commercialOfferId,
    }: OpenGlobalSubscriptionInput): void => {
      const target = ROUTE_BUILDERS.subscription(type, {
        payChannel,
        returnTo: returnTo ?? undefined,
        sourceCharacterSlug,
        analytics,
        chatActionId,
        planId,
        commercialOfferId,
      });

      behaviorAnalytics.rechargeModalOpen(analytics);

      const nextUrl = resolveAuthenticatedNavigation({
        loginStatus,
        targetUrl: target,
      });

      if (shouldReplace) {
        router.replace(nextUrl);
        return;
      }
      router.push(nextUrl);
    },
    [getDefaultPayChannel, loginStatus, router],
  );

  return useMemo(
    () => ({
      push,
      replace,
      back,
      openAuth,
      openSubscription,
      getDefaultPayChannel,
      isAuthenticatedUser,
    }),
    [
      back,
      getDefaultPayChannel,
      isAuthenticatedUser,
      openAuth,
      openSubscription,
      push,
      replace,
    ],
  );
}
