'use strict';

// ── Bootstrap ─────────────────────────────────────────────────────────────────
const { initializeEnvironment } = require('./bootstrap/environment');
initializeEnvironment();

// P2-D FIX: Leer versión desde package.json en lugar de hardcodearla
const { version: APP_VERSION } = require('../package.json');

// ── Módulos core ──────────────────────────────────────────────────────────────
const express      = require('express');
const http         = require('http');

// ── Utilidades internas ───────────────────────────────────────────────────────
const logger       = require('./utils/logger');
const { getPool, getPoolStats } = require('./db');

// ── Middleware ────────────────────────────────────────────────────────────────
const { authMiddleware, generarTokenPair, rotarRefreshToken, revocarRefreshToken } = require('./middleware/auth');
const { limiterRefresh, limiterPDF } = require('./middleware/rateLimiter');

// ── Licencias ─────────────────────────────────────────────────────────────────
const { initLicense, startLicenseWatcher, licenseGuard, requireLicenseModule, hasModule } = require('./license/licenseValidator');
initLicense();
startLicenseWatcher((result) => {
  logger.error({ event: 'license_invalidated_runtime', reason: result.reason });
  try { require('./modules/billing-print').bootstrap.bootstrapBillingModules({ source: 'license_watcher_invalidated' }); } catch (err) { logger.warn({ event: 'billing_print_license_invalidation_failed', error: err.message }); }
});

// ── Servicios ─────────────────────────────────────────────────────────────────
const socketService        = require('./services/socketService');
const liveNotifications    = require('./services/liveNotificationService');
const updateRecovery       = require('./services/updateRecoveryService');
const { ensureMetasTable } = require('./services/metasService');
const { startAgent } = require('./agent');
const billingPrint = require('./modules/billing-print');
const { ensureBillingSchema } = require('./modules/billing/billing.schema');
const arkhonCard = require('./modules/arkhon-card');
const { getRuntimeMode, isCloudRuntime, isConnectorRuntime } = require('./runtimeMode');
const offlineSync = require('./modules/sync');
const { isSetupComplete } = require('./setupState');
const securityStore = require('./security/securityStore');
const { registerPreAuthFeatureRoutes, registerProtectedApiRoutes } = require('./http/registerApiRoutes');
const { registerPublicApiRoutes } = require('./http/registerPublicApiRoutes');
const { configureHttpApp, registerFallbackHandlers } = require('./http/configureHttpApp');
const { configureLowMemoryMode } = require('./runtime/lowMemoryMode');
const { createSocketServer } = require('./realtime/createSocketServer');
const { registerProcessSupervision } = require('./runtime/processSupervision');
const { startConnector, startOperationalSchedulers } = require('./runtime/operationalServices');
const { startServer } = require('./bootstrap/startServer');

// ── Express + HTTP + Socket.IO ────────────────────────────────────────────────
const app    = express();
const server = http.createServer(app);
const PORT   = parseInt(process.env.PORT) || 3001;
const RUNTIME_MODE = getRuntimeMode();

const { enabled: LOW_MEMORY } = configureLowMemoryMode({ logger });

const { io, publicDomain: LHR_DOMAIN } = createSocketServer(server, { port: PORT, logger });

configureHttpApp(app, { logger });

// ── Rutas públicas (sin autenticación) ────────────────────────────────────────

// Configuración del formulario de login (solo nombres y roles, nunca PINs)
registerPublicApiRoutes(app, {
  appVersion: APP_VERSION,
  securityStore,
  logger,
  generarTokenPair,
  rotarRefreshToken,
  revocarRefreshToken,
  limiterRefresh,
  getPool,
  getPoolStats,
  isSetupComplete,
});

registerPreAuthFeatureRoutes(app, { requireLicenseModule });

// ARKHON Local Connector: opt-in, fail-safe. El portal local no depende del cloud.
startConnector({ app, runtimeMode: RUNTIME_MODE, isConnectorRuntime, isSetupComplete, startAgent, logger });

// ── Rutas protegidas ──────────────────────────────────────────────────────────
registerProtectedApiRoutes(app, {
  authMiddleware,
  licenseGuard,
  requireLicenseModule,
  billingPrint,
  arkhonCard,
  offlineSync,
  limiterRefresh,
  limiterPDF,
  socketService,
  getPool,
});

// Iniciar tareas operativas solo cuando el configurador ya termino.
startOperationalSchedulers({
  runtimeMode: RUNTIME_MODE,
  isCloudRuntime,
  isSetupComplete,
  billingPrint,
  offlineSync,
  arkhonCard,
  logger,
});

registerFallbackHandlers(app, { logger });

registerProcessSupervision({ logger, lowMemory: LOW_MEMORY });

// ── Inicio del servidor ───────────────────────────────────────────────────────
startServer({
  server,
  io,
  port: PORT,
  publicDomain: LHR_DOMAIN,
  logger,
  liveNotifications,
  socketService,
  updateRecovery,
  startupTasks: {
    ensureMetasTable,
    ensureBillingSchema: hasModule('billing')
      ? ensureBillingSchema
      : async () => logger.info({ event: 'startup_migration_skipped', name: 'billing', reason: 'module_not_licensed' }),
    ensureArkhonCardSchema: process.env.ARKHON_CARD_SCHEMA_ON_START === 'false'
      ? async () => logger.info({ event: 'startup_migration_skipped', name: 'arkhon-card', reason: 'configured_on_demand' })
      : arkhonCard.service.ensureArkhonCardSchema,
  },
});
