import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { AppModule } from './app.module';
import { ConfigService } from '@nestjs/config';
import { SwaggerModule } from '@nestjs/swagger/dist/swagger-module';
import { DocumentBuilder } from '@nestjs/swagger';
import { ValidationPipe } from '@nestjs/common';
import { LogRequestInterceptor } from './common/interceptors/log-request.interceptor';
import * as path from 'path';
import * as express from 'express';

/** GET/HEAD photos : CORS + CORP pour Flutter web (cross-origin `Image.network`). Pas de cookie sur ces URLs. */
function setStaticImageCorsHeaders(res: express.Response): void {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin');
}

const staticImageServeOptions = {
  index: false,
  fallthrough: true,
  setHeaders: (res: express.Response) => setStaticImageCorsHeaders(res),
};

/** Préflight si le navigateur interroge OPTIONS sur les médias. */
function uploadsCorsPreflight(
  req: express.Request,
  res: express.Response,
  next: express.NextFunction,
): void {
  if (req.method === 'OPTIONS') {
    setStaticImageCorsHeaders(res);
    res.setHeader('Access-Control-Allow-Methods', 'GET, HEAD, OPTIONS');
    res.setHeader('Access-Control-Max-Age', '86400');
    res.status(204).end();
    return;
  }
  next();
}

/** Répertoire disque contenant le dossier `photos` (ex. /app/uploads si photos dans /app/uploads/photos). */
function resolveUploadsFilesystemRoot(): string {
  const raw = process.env.UPLOAD_PHOTOS_DIR?.trim();
  const photosDir = raw
    ? path.isAbsolute(raw)
      ? raw
      : path.resolve(process.cwd(), raw)
    : path.join(process.cwd(), 'uploads', 'photos');
  return path.dirname(photosDir);
}

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule, {
    logger: ['error', 'warn', 'log', 'debug', 'verbose'],
  });

  // Inscription (photos base64 dans le JSON) : sans limite > défaut Express (~100 ko) → 413/500 ou corps tronqué.
  app.useBodyParser('json', { limit: '15mb' });
  app.useBodyParser('urlencoded', { extended: true, limit: '15mb' });

  // CORS global **avant** les fichiers statiques pour que les réponses API et idéalement la chaîne Express restent cohérentes.
  app.enableCors({
    origin: true, // Reflète l’Origin (dev / prod) — routes API + cookies JWT
    methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
    allowedHeaders: ['Content-Type', 'Authorization', 'Accept'],
    credentials: true,
  });

  const expressApp = app.getHttpAdapter().getInstance();
  const uploadsRoot = resolveUploadsFilesystemRoot();

  // Photos : chemins stockés en base type /uploads/photos/...
  // En-têtes explicites sur les réponses fichier (les statics peuvent répondre sans repasser par la même couche que les contrôleurs).
  expressApp.use('/uploads', uploadsCorsPreflight);
  expressApp.use('/api/v1/uploads', uploadsCorsPreflight);

  app.useStaticAssets(uploadsRoot, {
    prefix: '/uploads/',
    ...staticImageServeOptions,
  });
  expressApp.use('/api/v1/uploads', express.static(uploadsRoot, staticImageServeOptions));

  // Log de chaque appel API si LOG_API_REQUESTS=true (mode debug)
  app.useGlobalInterceptors(new LogRequestInterceptor());

  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: true,
      forbidNonWhitelisted: true,
      transform: true,
    })
  );

  const configService = app.get(ConfigService);

  const port = configService.get<number>('app.port', 3000);
  app.setGlobalPrefix('api/v1');

  const config = new DocumentBuilder()
    .setTitle("P'titsPas API")
    .setDescription("API pour l'application P'titsPas")
    .setVersion('1.0.0')
    .addBearerAuth(
      {
        type: 'http',
        scheme: 'Bearer',
        bearerFormat: 'JWT',
        name: 'Authorization',
        description: 'Enter JWT token',
        in: 'header',
      },
      'access-token',
    )
    //.addServer('/api/v1')
    .build();

  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api/v1/swagger', app, document);



  await app.listen(port);
  console.log(`✅ P'titsPas API is running on: ${await app.getUrl()}`);
}

bootstrap().catch((err) => {
  console.error('❌ Error starting the application:', err);
  process.exit(1);
});
