import './utils/logger.js';
import express from 'express';
import session from 'express-session';
import connectSessionFileStore from 'session-file-store';
import helmet from 'helmet';
import cookieParser from 'cookie-parser';
import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const FileStore = connectSessionFileStore(session);

import { CONFIG } from './utils/config.js';
import { globalState, checkSiteStatus } from './utils/state.js';
import { discoverSources } from './core/discovery.js';
import { sourceRegistry } from './core/registry.js';
import { hasAnyUser, createUser } from './utils/userStore.js';

import authRoutes from './routes/auth.js';
import apiRoutes from './routes/api.js';
import jdRoutes from './routes/jd.js';
import proxyRoutes from './routes/proxy.js';
import viewRoutes from './routes/views.js';
import setupRoutes from './routes/setup.js';

const app = express();
const PORT = CONFIG.PORT;

// Configuration EJS
app.set('view engine', 'ejs');
app.set('views', path.join(process.cwd(), 'views'));

// Inject appVersion in all views
import fs from 'fs';
const packageJson = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8'));
app.locals.appVersion = packageJson.version;

// ========================= MIDDLEWARES SÉCURITÉ =========================

// CORS : désactivé (app self-hosted, pas besoin de cross-origin)
// Remplace l'ancien cors() ouvert qui permettait tout origin

app.use(helmet({
    contentSecurityPolicy: {
        directives: {
            "default-src": ["'self'"],
            "script-src": ["'self'", "'unsafe-inline'", "https://cdn.jsdelivr.net"],
            "script-src-attr": ["'unsafe-inline'"],
            "style-src": ["'self'", "'unsafe-inline'", "https://fonts.googleapis.com"],
            "font-src": ["'self'", "https://fonts.gstatic.com"],
            "img-src": ["'self'", "data:", "blob:", "https://www.google.com", "https://*.gstatic.com"],
            "connect-src": ["'self'"],
            "upgrade-insecure-requests": null,
        }
    },
    crossOriginResourcePolicy: { policy: "cross-origin" }
}));

// Body parser avec limite de taille — anti DoS mémoire
app.use(express.json({ limit: '1mb' }));
app.use(express.urlencoded({ extended: false, limit: '1mb' }));

app.set('trust proxy', 1);
app.use(cookieParser());

// Session avec sameSite: 'lax' — anti CSRF
app.use(session({
    store: new FileStore({
        path: './sessions',
        ttl: 48 * 60 * 60,
        retries: 10,       
        reapInterval: 3600    
    }),
    secret: CONFIG.SECRET,
    resave: false,
    saveUninitialized: false,
    cookie: {
        httpOnly: true,
        secure: 'auto',
        sameSite: 'lax',
        maxAge: 48 * 60 * 60 * 1000
    }
}));

// ========================= ROUTES =========================

// Setup route (doit être AVANT le gatekeeper dans viewRoutes)
app.use('/setup', setupRoutes);

// Routeur de vues EJS (inclut le setup gatekeeper)
app.use('/', viewRoutes);

// Enregistrement des routes API
app.use('/', authRoutes);
app.use('/', apiRoutes);
app.use('/', jdRoutes);
app.use('/', proxyRoutes);

// Serve frontend static files
app.use(express.static(path.join(process.cwd(), 'public')));

// ========================= DÉMARRAGE =========================

app.listen(PORT, async () => {
    console.log(`\n${'='.repeat(60)}`);
    console.log(`  Agora — API Server`);
    console.log(`${'='.repeat(60)}`);
    console.log(`Serveur API démarré sur http://localhost:${PORT}\n`);

    // ---- Bootstrap auto du premier admin via .env ----
    if (!hasAnyUser()) {
        if (CONFIG.ADMIN_USERNAME && CONFIG.ADMIN_PASSWORD) {
            try {
                createUser(CONFIG.ADMIN_USERNAME, CONFIG.ADMIN_PASSWORD, 'admin');
                console.log(`[Auth] ✅ Admin auto-créé depuis .env: "${CONFIG.ADMIN_USERNAME}"`);
            } catch (error: any) {
                console.error(`[Auth] ❌ Erreur création admin auto:`, error.message);
            }
        } else {
            console.log(`[Auth] ⚠️  Aucun utilisateur trouvé. Accédez à http://localhost:${PORT}/setup pour créer le premier admin.`);
        }
    }

    // Auto-discovery : scan sources/, import, health check
    await discoverSources();

    // Active les sources sauvegardées ou toutes les sources par défaut
    const { loadSettings } = await import('./utils/settingsManager.js');
    const settings = loadSettings();
    const availableSources = sourceRegistry.getAvailableNames();

    if (settings && settings.activeSources && Array.isArray(settings.activeSources)) {
        // Filtre pour ne garder que les sources qui sont toujours valides/enregistrées
        globalState.activeSources = settings.activeSources.filter((s: string) => availableSources.includes(s));
    } else {
        // Aucune sauvegarde trouvée, on active tout par défaut
        globalState.activeSources = availableSources;
    }

    console.log(`\nSource(s) par défaut: ${globalState.activeSources.map(s => s.toUpperCase()).join(', ') || 'Aucune'}`);

    const scheduleNextCheck = () => {
        const randomMinutes = Math.floor(Math.random() * (CONFIG.MAX_MINUTES - CONFIG.MIN_MINUTES + 1)) + CONFIG.MIN_MINUTES;
        console.log(`[Timer] Prochaine vérification dans ${randomMinutes} minutes.`);
        setTimeout(async () => { await checkSiteStatus(); scheduleNextCheck(); }, randomMinutes * 60 * 1000);
    };

    console.log("Lancement de la première vérification...");
    await checkSiteStatus();
    scheduleNextCheck();
});

process.on('SIGINT', () => { console.log('\nArrêt SIGINT...'); process.exit(0); });
process.on('SIGTERM', () => { console.log('\nArrêt SIGTERM...'); process.exit(0); });
