/**
 * FiveM server entry point — mirrors the original RageMP src/index.ts boot
 * sequence. The mp shim MUST be the very first import so that the global `mp`
 * object exists before any feature modules load.
 */

import './core/mp-shim';

import { install } from 'source-map-support';
import { ChatColors } from '../shared/const/chat-colors';
import { commandSystem } from './core/commands';
import { writeCommandManifestTxt } from './core/commands/command-manifest';
import { databaseSystem } from './core/database';
import { FeatureSystem } from './core/feature-system';
import { LogSystem, logSystem } from './core/log';
import { mongoSystem } from './core/mongo';
import { preloadSystem } from './core/preload';
import { redisSystem } from './core/redis';

// ---------------------------------------------------------------------------
// Feature imports — uncomment each one as it is ported.
// ---------------------------------------------------------------------------

import { playerSystem } from './features/player';
import { loginSystem } from './features/login';

// ---------------------------------------------------------------------------
// Boot
// ---------------------------------------------------------------------------

// source-map-support writes cache files; skip inside FiveM sandbox
if (typeof GetCurrentResourceName === 'undefined') { install(); }

const featuresParallel: FeatureSystem[] = [
    // timeSystem,
    // clothingSystem,
    // ... uncomment as features are ported
];

const featuresSeries: FeatureSystem[] = [
    playerSystem,
    loginSystem,
];

const SERVER_VER = '1.0';
const CLIENT_VER = '1.0';

mp.events.add('versionCheck', (player: PlayerMp, version: string) => {
    if (version !== CLIENT_VER) {
        LogSystem.Collect(`[${player.id}] ${player.name}`.yellow + ` connected with wrong client version ${version} (expected ${CLIENT_VER})`.red);
        player.notify(`Client version mismatch: ${version} (expected ${CLIENT_VER})`);
    }
});

(async () => {
    const start = Date.now();

    logSystem.init();

    await databaseSystem.init();
    await mongoSystem.init();
    await redisSystem.init();
    await preloadSystem.init();

    // Parallel features init
    await Promise.all(featuresParallel.map((f) => f.init()));

    // Series features init (order-dependent)
    for (const f of featuresSeries) {
        await f.init();
    }

    // postInit pass
    const allFeatures = [...featuresParallel, ...featuresSeries];
    for (const f of allFeatures) {
        if (f.postInit) await f.postInit();
    }

    commandSystem.init(allFeatures);
    // FiveM sandbox blocks fs writes; skip manifest generation in-resource
    if (typeof GetCurrentResourceName === 'undefined') {
        await writeCommandManifestTxt();
    }

    LogSystem.Collect(`Southwest Roleplay FiveM v${SERVER_VER} started in ${Date.now() - start}ms — Node.js ${process.version}`);

    mp.events.call('serverInitialized');
})();

// ---------------------------------------------------------------------------
// Graceful shutdown
// ---------------------------------------------------------------------------
let shuttingDown = false;

process.on('SIGINT', async () => {
    if (shuttingDown) { process.exit(0); return; }
    shuttingDown = true;

    mp.players.broadcast(`${ChatColors.testerRed}Server is restarting!`);
    LogSystem.Collect('[SHUTDOWN] Starting shutdown...');

    for (const player of mp.players.toArray()) {
        player.outputChatBox(`${ChatColors.cyan}You're being saved before the server shuts down!`);
        mp.events.call('playerQuit', player, 'server restarting');
    }

    await new Promise((r) => setTimeout(r, 1500));
    LogSystem.Collect('[SHUTDOWN] Goodbye!');
    process.exit(0);
});
