import Cookies from 'js-cookie';
import type { ReadonlyURLSearchParams } from 'next/navigation';

const ALLOWED_OAUTH_DESTINATION_HOSTS = ['chatgpt.com', 'ngrok-free.app', 'ngrok.io', 'api.connector.cc', 'stagingapi.connector.cc'];
type OAuthSearchParams = Pick<ReadonlyURLSearchParams, 'get' | 'toString'>;

const isAllowedOAuthDestination = (url: string) => {
    try {
        const parsed = new URL(url);
        return ALLOWED_OAUTH_DESTINATION_HOSTS.some(
            (host) => parsed.hostname === host || parsed.hostname.endsWith(`.${host}`)
        ) || (parsed.hostname.endsWith('.connector.cc') && parsed.pathname.includes('/oauth'));
    } catch {
        return false;
    }
};

export const isAllowedOAuthNextUrl = (nextUrl: string) => isAllowedOAuthDestination(nextUrl);

const isAllowedOAuthRequest = (params: OAuthSearchParams) => {
    const nextUrl = params.get('next');
    const redirectUri = params.get('redirect_uri');

    if (nextUrl && isAllowedOAuthDestination(nextUrl)) {
        return true;
    }

    if (redirectUri && isAllowedOAuthDestination(redirectUri)) {
        return true;
    }

    if (nextUrl) {
        try {
            const nestedRedirectUri = new URL(nextUrl).searchParams.get('redirect_uri');
            if (nestedRedirectUri && isAllowedOAuthDestination(nestedRedirectUri)) {
                return true;
            }
        } catch {
            return false;
        }
    }

    return false;
};

export const persistOAuthParams = (search: string) => {
    if (search.includes('next=')) {
        sessionStorage.setItem('oauth_params', search);
    }
};

const mergeOAuthParams = (searchParams: OAuthSearchParams) => {
    const params = new URLSearchParams(searchParams.toString());

    if (!params.get('next')) {
        const savedParams = sessionStorage.getItem('oauth_params');
        if (savedParams) {
            const normalizedParams = savedParams.startsWith('?') ? savedParams.slice(1) : savedParams;
            const storedParams = new URLSearchParams(normalizedParams);
            storedParams.forEach((value, key) => {
                if (!params.has(key)) {
                    params.set(key, value);
                }
            });
        }
    }

    if (!params.get('next')) {
        const pendingRedirect = Cookies.get('pending_redirect');
        if (pendingRedirect?.startsWith('/oauth/consent')) {
            const pendingParams = new URLSearchParams(pendingRedirect.split('?')[1] || '');
            pendingParams.forEach((value, key) => {
                if (!params.has(key)) {
                    params.set(key, value);
                }
            });
        }
    }

    return params;
};

export const getOAuthConsentRedirectPath = (searchParams: OAuthSearchParams) => {
    const params = mergeOAuthParams(searchParams);
    const nextUrl = params.get('next');

    if (!nextUrl || !isAllowedOAuthRequest(params)) {
        return null;
    }

    sessionStorage.removeItem('oauth_params');
    return `/oauth/consent?${params.toString()}`;
};
