import { initTracing } from '@goodgo/tracing';
import cookieParser from 'cookie-parser';
import cors from 'cors';
import express, { Express } from 'express';
import { rateLimit } from 'express-rate-limit';
import helmet from 'helmet';

import { appConfig } from './config/app.config';
import { setupSwagger } from './docs/swagger';
import { correlationMiddleware } from './middlewares/correlation.middleware';
import { errorHandler, notFoundHandler } from './middlewares/error.middleware';
import { requestLogger } from './middlewares/logger.middleware';
import { metricsMiddleware } from './middlewares/metrics.middleware';
import { createRouter } from './routes';

// EN: Initialize tracing
// VI: Khởi tạo tracing
if (process.env.TRACING_ENABLED === 'true') {
    initTracing({
        serviceName: process.env.SERVICE_NAME || 'microservice',
        otlpEndpoint: process.env.OTLP_ENDPOINT,
        enabled: true,
    });
}

const app: Express = express();

// EN: Security middleware
// VI: Middleware bảo mật
app.use(helmet());
app.use(
    cors({
        origin: appConfig.corsOrigin,
        credentials: true,
        methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
        allowedHeaders: ['Content-Type', 'Authorization', 'x-correlation-id', 'x-request-id'],
        exposedHeaders: ['x-correlation-id'],
    })
);

// EN: Rate limiting (more permissive for development)
// VI: Giới hạn số lượng request (cho phép nhiều hơn trong development)
const limiter = rateLimit({
    windowMs: 15 * 60 * 1000, // 15 minutes
    max: appConfig.nodeEnv === 'production' ? 100 : 1000, // 1000 for dev, 100 for prod
    message: {
        success: false,
        error: {
            code: 'RATE_LIMIT_EXCEEDED',
            message: 'Too many requests, please try again later',
        },
    },
    standardHeaders: true,
    legacyHeaders: false,
});
app.use('/api', limiter);

// EN: Correlation ID middleware (must be early)
// VI: Correlation ID middleware (phải đặt sớm)
app.use(correlationMiddleware());

// EN: Body parsing
// VI: Phân tích body request
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());

// EN: Request logging
// VI: Ghi log request
app.use(requestLogger);

// EN: Metrics
// VI: Metrics
app.use(metricsMiddleware);

// EN: Routes with async error handling
// VI: Routes với async error handling
app.use(createRouter());
// In main.ts it was `app.use(createRouter())`. Let's check routes/index.ts to see if it adds prefix.
// The integration test used `createRouter` directly in main.
// Let's keep it as `app.use(createRouter())` unless I know better.
// Actually `routes/index.ts` creates a router.
// Looking at previous `main.ts`: `app.use(createRouter())`
// I'll stick to that. Or check auth.routes.ts.
// auth.routes.ts says: `const router = express.Router(); router.post('/register'...)`
// So mounting at root means `/auth/register`? Or `/api/v1/auth`?
// I need to check `routes/index.ts`.

// Checking routes/index.ts content (from memory/context):
// It refactored to import feature modules.
// Usually: router.use('/auth', authRoutes).
// If createsRouter returns a router with paths, then `app.use(createRouter())` mounts them at `/`.
// Let's assume `createRouter()` returns the main router.

// RE-READING main.ts view:
// app.use(createRouter());

// BUT usually API is at `/api/v1/...`
// The `routes/index.ts` might handle `/api/v1` prefix or `main.ts` should.
// Let's keep `app.use(createRouter())` for now to match main.ts. Use exact logic.

// Wait, I am overwriting app.ts.
// I will verify `routes/index.ts` content later if tests fail 404.

// EN: Setup Swagger documentation
// VI: Thiết lập tài liệu Swagger
setupSwagger(app, '/api-docs');

// EN: Error handling
// VI: Xử lý lỗi
app.use(notFoundHandler);
app.use(errorHandler);

export { app };
