import type { InertiaLinkProps } from '@inertiajs/vue3';
import { usePage } from '@inertiajs/vue3';
import type { ComputedRef, DeepReadonly } from 'vue';
import { computed, readonly } from 'vue';
import { toUrl } from '@/lib/utils';

export type UseCurrentUrlReturn = {
    currentUrl: DeepReadonly<ComputedRef<string>>;

    isCurrentUrl: (
        urlToCheck: NonNullable<InertiaLinkProps['href']>,
        currentUrl?: string,
        exact?: boolean,
    ) => boolean;

    whenCurrentUrl: <T, F = null>(
        urlToCheck: NonNullable<InertiaLinkProps['href']>,
        ifTrue: T,
        ifFalse?: F,
        exact?: boolean,
    ) => T | F;
};

const page = usePage();

const currentUrlReactive = computed(
    () =>
        new URL(
            page.url,
            typeof window !== 'undefined'
                ? window.location.origin
                : 'http://localhost',
        ).pathname,
);

export function useCurrentUrl(): UseCurrentUrlReturn {
    function isCurrentUrl(
        urlToCheck: NonNullable<InertiaLinkProps['href']>,
        currentUrl?: string,
        exact = false,
    ): boolean {
        const urlToCompare = currentUrl ?? currentUrlReactive.value;
        const urlString = toUrl(urlToCheck);

        let pathname: string;

        if (!urlString.startsWith('http')) {
            pathname = urlString;
        } else {
            try {
                pathname = new URL(urlString).pathname;
            } catch {
                return false;
            }
        }

        // Normalize trailing slash
        const current = urlToCompare.replace(/\/+$/, '') || '/';
        const target = pathname.replace(/\/+$/, '') || '/';

        // Exact matching
        if (exact) {
            return target === current;
        }

        // Root must remain exact
        if (target === '/') {
            return current === '/';
        }

        // Match target and all child routes
        return current === target || current.startsWith(`${target}/`);
    }

    function whenCurrentUrl<T, F = null>(
        urlToCheck: NonNullable<InertiaLinkProps['href']>,
        ifTrue: T,
        ifFalse: F = null as F,
        exact = false,
    ): T | F {
        return isCurrentUrl(urlToCheck, undefined, exact)
            ? ifTrue
            : ifFalse;
    }

    return {
        currentUrl: readonly(currentUrlReactive),
        isCurrentUrl,
        whenCurrentUrl,
    };
}