// src/app.js
// AI Assistant API 서버 메인 엔트리포인트

require('dotenv').config();

const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const compression = require('compression');
const rateLimit = require('express-rate-limit');
const swaggerUi = require('swagger-ui-express');
const swaggerSpec = require('./config/swagger.config');

const logger = require('./config/logger.config');
const { sequelize } = require('./models');
const routes = require('./routes');
const errorHandler = require('./middlewares/error-handler.middleware');

const app = express();
// VEXPLOR 내장 시 backend-node가 이 포트로 프록시하므로 기본 3100 사용
const PORT = process.env.PORT || 3100;

// ===========================================
// 미들웨어 설정
// ===========================================

// Trust proxy (Docker/Nginx 환경)
app.set('trust proxy', 1);

// CORS 설정 (helmet보다 먼저 설정)
app.use(cors({
  origin: true, // 모든 origin 허용
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],
}));

// Preflight 요청 처리
app.options('*', cors());

// 보안 헤더 (CORS 이후에 설정)
app.use(helmet({
  crossOriginResourcePolicy: { policy: 'cross-origin' },
  crossOriginOpenerPolicy: { policy: 'unsafe-none' },
}));

// 요청 본문 파싱
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true }));

// 압축
app.use(compression());

// Rate Limiting (전역)
const limiter = rateLimit({
  windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS, 10) || 60000,
  max: parseInt(process.env.RATE_LIMIT_MAX_REQUESTS, 10) || 100,
  message: {
    success: false,
    error: {
      code: 'RATE_LIMIT_EXCEEDED',
      message: '요청 한도를 초과했습니다. 잠시 후 다시 시도해주세요.',
    },
  },
  standardHeaders: true,
  legacyHeaders: false,
});
app.use(limiter);

// 요청 로깅
app.use((req, res, next) => {
  const start = Date.now();
  res.on('finish', () => {
    const duration = Date.now() - start;
    logger.info(`${req.method} ${req.originalUrl} ${res.statusCode} ${duration}ms`);
  });
  next();
});

// ===========================================
// 헬스 체크
// ===========================================

app.get('/health', (req, res) => {
  res.json({
    success: true,
    data: {
      status: 'healthy',
      timestamp: new Date().toISOString(),
      uptime: process.uptime(),
    },
  });
});

// ===========================================
// Swagger API 문서
// ===========================================

app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec, {
  explorer: true,
  customCss: '.swagger-ui .topbar { display: none }',
  customSiteTitle: 'AI Assistant API 문서',
  swaggerOptions: {
    persistAuthorization: true,
    displayRequestDuration: true,
  },
}));

// Swagger JSON
app.get('/api-docs.json', (req, res) => {
  res.setHeader('Content-Type', 'application/json');
  res.send(swaggerSpec);
});

// ===========================================
// API 라우트
// ===========================================

app.use('/api/v1', routes);

// ===========================================
// 404 처리
// ===========================================

app.use((req, res) => {
  res.status(404).json({
    success: false,
    error: {
      code: 'NOT_FOUND',
      message: `요청한 리소스를 찾을 수 없습니다: ${req.method} ${req.originalUrl}`,
    },
  });
});

// ===========================================
// 에러 핸들러
// ===========================================

app.use(errorHandler);

// ===========================================
// 서버 시작
// ===========================================

async function startServer() {
  try {
    // 데이터베이스 연결
    await sequelize.authenticate();
    logger.info('✅ 데이터베이스 연결 성공');

    // 테이블 동기화 (테이블이 없으면 생성)
    await sequelize.sync();
    logger.info('✅ 데이터베이스 스키마 동기화 완료');

    // 초기 데이터 설정 (관리자 계정, LLM 프로바이더)
    const initService = require('./services/init.service');
    await initService.initialize();

    // 서버 시작
    app.listen(PORT, () => {
      logger.info(`🚀 AI Assistant API 서버가 포트 ${PORT}에서 실행 중입니다`);
      logger.info(`📚 API 문서 (Swagger): http://localhost:${PORT}/api-docs`);
      logger.info(`📚 API 엔드포인트: http://localhost:${PORT}/api/v1`);
    });
  } catch (error) {
    logger.error('❌ 서버 시작 실패:', error);
    process.exit(1);
  }
}

// 프로세스 종료 처리
process.on('SIGTERM', async () => {
  logger.info('SIGTERM 신호 수신, 서버 종료 중...');
  await sequelize.close();
  process.exit(0);
});

process.on('SIGINT', async () => {
  logger.info('SIGINT 신호 수신, 서버 종료 중...');
  await sequelize.close();
  process.exit(0);
});

startServer();

module.exports = app;
