import { createJwtUtils } from '@bytelyst/auth';
import { config } from '../config/index.js';
import logger from '../utils/logger.js';
import { supabaseService } from './SupabaseService.js';

export interface VerifiedTradingAuth {
    userId: string | null;
    role?: string;
    email?: string;
    displayName?: string;
    plan?: string;
    productId?: string;
    source: 'platform' | 'supabase' | null;
    error?: string;
}

let cachedJwtUtils: ReturnType<typeof createJwtUtils> | null | undefined;

function normalizeRole(role: unknown): string | undefined {
    const value = String(role || '').trim().toLowerCase();
    return value || undefined;
}

function getPlatformJwtUtils(): ReturnType<typeof createJwtUtils> | null {
    if (cachedJwtUtils !== undefined) {
        return cachedJwtUtils;
    }

    if (!config.PLATFORM_AUTH_ENABLED) {
        cachedJwtUtils = null;
        return cachedJwtUtils;
    }

    const hasHs256 = Boolean(config.JWT_SECRET);
    const hasRs256 = Boolean(config.PLATFORM_JWT_PUBLIC_KEY || config.PLATFORM_JWT_JWKS_URL);

    if (!hasHs256 && !hasRs256) {
        cachedJwtUtils = null;
        return cachedJwtUtils;
    }

    cachedJwtUtils = createJwtUtils({
        issuer: config.PLATFORM_JWT_ISSUER,
        algorithm: hasRs256 ? 'RS256' : 'HS256',
        rsaPublicKey: config.PLATFORM_JWT_PUBLIC_KEY || undefined,
        jwksUrl: config.PLATFORM_JWT_JWKS_URL || undefined,
    });

    return cachedJwtUtils;
}

export async function verifyTradingAccessToken(token: string): Promise<VerifiedTradingAuth> {
    const jwtUtils = getPlatformJwtUtils();
    if (jwtUtils) {
        try {
            const payload = await jwtUtils.verifyToken(token);
            const productId = String(payload?.productId || '').trim();
            if (!payload?.sub) {
                return { userId: null, source: null, error: 'Platform token missing subject claim' };
            }
            if (payload?.type && payload.type !== 'access') {
                return { userId: null, source: null, error: 'Platform token is not an access token' };
            }
            if (productId && productId !== config.PRODUCT_ID) {
                return { userId: null, source: null, error: `Platform token product mismatch (${productId})` };
            }

            return {
                userId: String(payload.sub),
                role: normalizeRole(payload.role),
                email: typeof payload.email === 'string' ? payload.email : undefined,
                displayName: typeof payload.displayName === 'string'
                    ? payload.displayName
                    : typeof payload.name === 'string'
                        ? payload.name
                        : undefined,
                plan: typeof payload.plan === 'string' ? payload.plan : undefined,
                productId: productId || config.PRODUCT_ID,
                source: 'platform',
            };
        } catch (error) {
            logger.warn(`[Auth] Platform token verification failed, falling back to legacy verifier: ${error instanceof Error ? error.message : 'unknown error'}`);
        }
    }

    const legacy = await supabaseService.verifyAccessToken(token);
    if (!legacy.userId) {
        return {
            userId: null,
            source: null,
            error: legacy.error || 'invalid token',
        };
    }

    return {
        userId: legacy.userId,
        source: 'supabase',
    };
}

export async function isTradingAdmin(userId: string, tokenRole?: string | null): Promise<boolean> {
    const normalizedRole = normalizeRole(tokenRole);
    if (normalizedRole === 'admin' || normalizedRole === 'super_admin') {
        return true;
    }
    return supabaseService.isAdmin(userId);
}
