import express, { Application } from 'express';
import cors from 'cors';
import { config } from 'dotenv';
import { randomUUID } from 'crypto';
import { Config } from './types/api';
import { textToImageRouter } from './routes/textToImage';
import { imagesRouter } from './routes/images';
import { uploadRouter } from './routes/upload';
import bootstrapRoutes from './routes/bootstrap';
import adminKeysRoutes from './routes/admin/keys';
import { v1Router } from './routes/v1';
import { cdnRouter } from './routes/cdn';
import { errorHandler, notFoundHandler } from './middleware/errorHandler';

// Load environment variables
config();

// Application configuration
export const appConfig: Config = {
  port: parseInt(process.env['PORT'] || '3000'),
  geminiApiKey: process.env['GEMINI_API_KEY'] || '',
  resultsDir: './results',
  uploadsDir: './uploads/temp',
  maxFileSize: 5 * 1024 * 1024, // 5MB
  maxFiles: 3,
};

// Create Express application
export const createApp = (): Application => {
  const app = express();

  // Middleware - CORS configuration (allow all origins)
  app.use(
    cors({
      origin: true, // Allow all origins
      credentials: true,
      methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
      allowedHeaders: ['Content-Type', 'Authorization', 'X-API-Key'],
      exposedHeaders: ['X-Request-ID'],
    }),
  );

  app.use(express.json({ limit: '10mb' }));
  app.use(express.urlencoded({ extended: true, limit: '10mb' }));

  // Request ID middleware for logging
  app.use((req, res, next) => {
    req.requestId = randomUUID();
    res.setHeader('X-Request-ID', req.requestId);
    next();
  });

  // Health check endpoint
  app.get('/health', (_req, res) => {
    const health = {
      status: 'healthy',
      timestamp: new Date().toISOString(),
      uptime: process.uptime(),
      environment: process.env['NODE_ENV'] || 'development',
      version: process.env['npm_package_version'] || '1.0.0',
    };

    console.log(`[${health.timestamp}] Health check - ${health.status}`);
    res.json(health);
  });

  // API info endpoint
  app.get('/api/info', async (req: any, res) => {
    const info: any = {
      name: 'Banatie - Nano Banana Image Generation API',
      version: '1.0.0',
      description:
        'REST API service for AI-powered image generation using Gemini Flash Image model',
      endpoints: {
        'GET /health': 'Health check',
        'GET /api/info': 'API information',
        'POST /api/text-to-image': 'Generate images from text prompt only (JSON)',
      },
      limits: {
        maxFileSize: `${appConfig.maxFileSize / (1024 * 1024)}MB`,
        maxFiles: appConfig.maxFiles,
        supportedFormats: ['PNG', 'JPEG', 'JPG', 'WebP'],
      },
    };

    // If API key is provided, validate and return key info
    const providedKey = req.headers['x-api-key'] as string;
    if (providedKey) {
      try {
        const { ApiKeyService } = await import('./services/ApiKeyService');
        const apiKeyService = new ApiKeyService();
        const apiKey = await apiKeyService.validateKey(providedKey);

        if (apiKey) {
          // Use slugs from validated API key (already fetched via LEFT JOIN)
          info.authenticated = true;
          info.keyInfo = {
            type: apiKey.keyType,
            organizationId: apiKey.organizationId,
            organizationSlug: apiKey.organizationSlug,
            projectId: apiKey.projectId,
            projectSlug: apiKey.projectSlug,
            expiresAt: apiKey.expiresAt,
          };
        }
      } catch (error) {
        // Ignore errors, just don't add key info
      }
    }

    console.log(`[${new Date().toISOString()}] API info requested`);
    res.json(info);
  });

  // Public routes (no authentication)
  // CDN routes for serving images and live URLs (public, no auth)
  app.use('/cdn', cdnRouter);

  // Bootstrap route (no auth, but works only once)
  app.use('/api/bootstrap', bootstrapRoutes);

  // Admin routes (require master key)
  app.use('/api/admin/keys', adminKeysRoutes);

  // API v1 routes (versioned, require valid API key)
  app.use('/api/v1', v1Router);

  // Protected API routes (require valid API key) - Legacy
  app.use('/api', textToImageRouter);
  app.use('/api', imagesRouter);
  app.use('/api', uploadRouter);

  // Error handling middleware (must be last)
  app.use(notFoundHandler);
  app.use(errorHandler);

  return app;
};

// Extend Express Request type to include requestId
declare global {
  namespace Express {
    interface Request {
      requestId: string;
    }
  }
}
