
import { TRPCError } from "@trpc/server";

// --- Rate Limiting ---
interface RateLimitInfo {
    count: number;
    resetTime: number;
}

const rateLimitStore = new Map<string, RateLimitInfo>();

// Clean up old entries every 5 minutes
setInterval(() => {
    const now = Date.now();
    for (const [key, value] of rateLimitStore.entries()) {
        if (now > value.resetTime) {
            rateLimitStore.delete(key);
        }
    }
}, 5 * 60 * 1000);

export function checkRateLimit(key: string, limit: number, windowMs: number) {
    const now = Date.now();
    const info = rateLimitStore.get(key);

    if (!info || now > info.resetTime) {
        rateLimitStore.set(key, { count: 1, resetTime: now + windowMs });
        return;
    }

    if (info.count >= limit) {
        throw new TRPCError({
            code: "TOO_MANY_REQUESTS",
            message: "Trop de requêtes. Veuillez réessayer plus tard.",
        });
    }

    info.count++;
}

// --- Sanitation ---
// Basic robust HTML escaping
export function escapeHtml(unsafe: string): string {
    if (typeof unsafe !== 'string') return unsafe;
    return unsafe
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&#039;");
}

// Strip all HTML tags
export function stripHtml(html: string): string {
    if (typeof html !== 'string') return html;
    return html.replace(/<[^>]*>?/gm, '');
}

export function sanitizeInput(input: any): any {
    if (typeof input === 'string') {
        return input.trim(); // We don't escape HTML on input to avoid double-escaping in React forms. React handles XSS on output.
    }
    if (Array.isArray(input)) {
        return input.map(sanitizeInput);
    }
    if (typeof input === 'object' && input !== null) {
        const newObj: any = {};
        for (const key in input) {
            newObj[key] = sanitizeInput(input[key]);
        }
        return newObj;
    }
    return input;
}

// --- CSRF ---
// Since we use HttpOnly cookies, we are safe from XSS reading the token.
// We need to protect against CSRF.
// For APIs, checking Origin/Referer is a strong defense.
// We can also use a Double Submit Cookie pattern if needed, but Origin is usually enough for modern browsers with SameSite=Lax/Strict.

export function checkOrigin(req: any) {
    const origin = req.headers.origin || req.headers.referer;
    // Allow requests with no origin (e.g. server-to-server or initial page load)
    if (!origin) return true;

    // Dynamic allow list
    const allowedOrigins = [
        process.env.VITE_PUBLIC_APP_URL,
        'https://leifo.fr',
        'https://www.leifo.fr',
        'http://localhost:5000',
        'http://localhost:3000',
        'http://127.0.0.1:5000',
    ].filter(Boolean);

    // Check against allowed list
    const isAllowedInList = allowedOrigins.some(allowed => origin.startsWith(allowed!));
    if (isAllowedInList) return true;

    // Check against Host header (Same-Origin fallback for dynamic environments)
    // construct protocol + host
    const host = req.headers.host;
    if (host && origin.includes(host)) {
        return true;
    }

    return false;
}
