import { NestFactory } from '@nestjs/core';
import * as fs from 'fs';
import { AppModule } from './app.module';
import { ValidationPipe, Logger } from '@nestjs/common';
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
import { IoAdapter } from '@nestjs/platform-socket.io';
import * as express from 'express';
import * as Handlebars from 'handlebars';
import * as bodyParser from 'body-parser';

// ═══════════════════════════════════════════════════════════════════════════
// 🛡️  GLOBAL ERROR HANDLERS — prevents server crash on WiFi drops / DB issues
// Registered at module level so they catch errors during bootstrap too
// ═══════════════════════════════════════════════════════════════════════════
const globalLogger = new Logger('GlobalErrorHandler');

process.on('uncaughtException', (error: Error) => {
  globalLogger.error(
    `🔥 Uncaught Exception (server will NOT crash): ${error.message}`,
  );
  if (error.stack) globalLogger.error(error.stack);
  // Don't exit — let the app keep running
});

process.on('unhandledRejection', (reason: any) => {
  const msg = reason?.message || String(reason);

  // Network errors are expected when WiFi switches — log quietly
  if (
    msg.includes('ECONNRESET') ||
    msg.includes('PROTOCOL_CONNECTION_LOST') ||
    msg.includes('ETIMEDOUT') ||
    msg.includes('ENOTFOUND') ||
    msg.includes('ECONNREFUSED') ||
    msg.includes('EPIPE')
  ) {
    globalLogger.warn(`⚠️  Network error (handled, auto-recovering): ${msg}`);
    return;
  }

  globalLogger.error(`🔥 Unhandled Rejection: ${msg}`);
  if (reason?.stack) globalLogger.error(reason.stack);
  // Don't exit
});

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule, {
    abortOnError: false, // ✅ don't crash on startup errors
  });

  console.log('NODE_OPTIONS:', process.env.NODE_OPTIONS);
  console.log('JWT_SECRET loaded:', !!process.env.JWT_SECRET);

  // Body parsers
  // Body parsers
  app.use(bodyParser.urlencoded({ limit: '500mb', extended: true }));
  app.use(bodyParser.json({ limit: '500mb' }));
  app.use(require('express').json({ limit: '500mb' }));
  app.use(require('express').urlencoded({ limit: '500mb', extended: true }));

  // Handlebars helpers
  Handlebars.registerHelper('addSpaces', function (text) {
    if (!text) return '';
    return String(text).replace(/,\s*/g, ', ');
  });

  // Upload directory check
  const uploadDir = join(process.cwd(), 'uploads', 'Planning', 'Field', 'desk');
  if (fs.existsSync(uploadDir)) {
    const files = fs.readdirSync(uploadDir);
    console.log(`📂 Upload directory exists with ${files.length} files`);
    console.log(`   First 5 files:`, files.slice(0, 5));
  } else {
    console.log(`⚠️ Upload directory does NOT exist: ${uploadDir}`);
  }

  // Static assets
  app.useStaticAssets(join(process.cwd(), 'uploads'), { prefix: '/uploads/' });
  app.use('/static', express.static(join(__dirname, '..', 'src', 'assets')));

  // CORS
  app.enableCors({
    origin: [
      'http://localhost:3021', // dev frontend
      'https://crm.qrsyst.com', // ✅ production frontend
      'https://qrsyst.com', // ✅ public verify page (cross-domain calls)
    ],
    methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
    allowedHeaders: 'Content-Type, Authorization',
    credentials: true,
  });

  // Global prefix
  app.setGlobalPrefix('api', {
    exclude: ['/uploads/(.*)'],
  });

  // Global validation
  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: false,
      forbidNonWhitelisted: false,
      transform: true,
      transformOptions: { enableImplicitConversion: true },
    }),
  );

  // ✅ FIX for NestJS 11 — init app first, get HTTP server, THEN set adapter
  await app.init();
  const httpServer = app.getHttpServer();
  app.useWebSocketAdapter(new IoAdapter(httpServer));

  const port = process.env.PORT ?? 3008;
  await app.listen(port, '0.0.0.0');

  console.log(`🔥 NestJS server running at http://localhost:${port}/api`);
  console.log(`📁 Static files served from: ${join(process.cwd(), 'uploads')}`);
  console.log(`Server running on port ${port}`);
}

bootstrap().catch((err) => {
  console.error('Bootstrap failed:', err);
  // Don't process.exit — let it retry naturally
});
