import type { Page } from '@inertiajs/core';
import type { PageProps } from '@/types/inertia';
import type { ActiveSubscription } from '@/types/subscription';
import { router } from '@inertiajs/vue3';

/** Paths still reachable while PAYG payment is overdue. */
const ALLOWED_OVERDUE_PATH_PREFIXES = [
    '/account-blocked',
    '/cards',
    '/pay-as-you-go',
    '/usage',
];

/**
 * Paths still reachable during LastChance (Story 4 renew must stay open).
 * Archival countdown UX + packages/renew paths stay reachable while blocked.
 */
const ALLOWED_LAST_CHANCE_PATH_PREFIXES = [
    '/account-blocked',
    '/cards',
    '/packages',
    '/subscriptions',
    '/usage',
    '/history',
    '/pay-as-you-go',
];

let currentPage: Page | null = null;

export function isSubscriptionOverdue(
    subscription: ActiveSubscription | null | undefined,
): boolean {
    return subscription?.status === 'overdue';
}

export function isSubscriptionInLastChance(
    subscription: ActiveSubscription | null | undefined,
): boolean {
    return subscription?.in_last_chance_phase === true;
}

function getSubscriptionFromPage(page: Page): ActiveSubscription | null | undefined {
    const user = (page.props as PageProps)?.auth?.user;

    if (!user) {
        return null;
    }

    return user.ActiveSubscription
        ?? (user as { active_subscription?: ActiveSubscription | null }).active_subscription
        ?? null;
}

function normalizePath(url: string): string {
    try {
        return new URL(url, window.location.origin).pathname;
    } catch {
        return url;
    }
}

function isAllowedPath(pathname: string, prefixes: string[]): boolean {
    return prefixes.some((prefix) => pathname === prefix || pathname.startsWith(`${prefix}/`));
}

function shouldRedirect(page: Page, targetUrl: string): boolean {
    const subscription = getSubscriptionFromPage(page);
    const pathname = normalizePath(targetUrl);

    if (isSubscriptionOverdue(subscription)) {
        return !isAllowedPath(pathname, ALLOWED_OVERDUE_PATH_PREFIXES);
    }

    if (isSubscriptionInLastChance(subscription)) {
        return !isAllowedPath(pathname, ALLOWED_LAST_CHANCE_PATH_PREFIXES);
    }

    return false;
}

function redirectToBlockedPage(): void {
    router.visit(window.route('account.blocked'), { replace: true });
}

export function enforceAccountBlockedRedirect(page: Page): void {
    currentPage = page;

    if (shouldRedirect(page, page.url)) {
        redirectToBlockedPage();
    }
}

export function setupAccountBlockedGuard(): void {
    router.on('before', (event) => {
        if (!currentPage) {
            return;
        }

        if (!shouldRedirect(currentPage, event.detail.visit.url.toString())) {
            return;
        }

        event.preventDefault();
        redirectToBlockedPage();
    });

    router.on('navigate', (event) => {
        currentPage = event.detail.page;

        if (!shouldRedirect(event.detail.page, event.detail.page.url)) {
            return;
        }

        redirectToBlockedPage();
    });
}
