import { Response, Router } from 'express';
import type { Router as RouterType } from 'express';
import { randomUUID } from 'crypto';
import { StorageFactory } from '../services/StorageFactory';
import { asyncHandler } from '../middleware/errorHandler';
import { validateApiKey } from '../middleware/auth/validateApiKey';
import { requireProjectKey } from '../middleware/auth/requireProjectKey';
import { rateLimitByApiKey } from '../middleware/auth/rateLimiter';
import { uploadSingleImage, handleUploadErrors } from '../middleware/upload';
import { UploadFileResponse } from '../types/api';

export const uploadRouter: RouterType = Router();

/**
 * POST /api/upload - Upload a single image file
 */
uploadRouter.post(
  '/upload',
  // Authentication middleware
  validateApiKey,
  requireProjectKey,
  rateLimitByApiKey,

  // File upload middleware
  uploadSingleImage,
  handleUploadErrors,

  // Main handler
  asyncHandler(async (req: any, res: Response) => {
    const timestamp = new Date().toISOString();
    const requestId = req.requestId;

    // Check if file was provided
    if (!req.file) {
      const errorResponse: UploadFileResponse = {
        success: false,
        message: 'File upload failed',
        error: 'No file provided',
      };
      return res.status(400).json(errorResponse);
    }

    // Extract org/project slugs from validated API key
    const orgSlug = req.apiKey?.organizationSlug || process.env['DEFAULT_ORG_SLUG'] || 'default';
    const projectSlug = req.apiKey?.projectSlug || process.env['DEFAULT_PROJECT_SLUG'] || 'main'; // Guaranteed by requireProjectKey middleware

    console.log(
      `[${timestamp}] [${requestId}] Starting file upload for org:${orgSlug}, project:${projectSlug}`,
    );

    const file = req.file;

    try {
      // Initialize storage service
      const storageService = await StorageFactory.getInstance();

      // Generate imageId (UUID) - this will be the filename in storage
      const imageId = randomUUID();

      // Upload file to MinIO
      // Path format: {orgSlug}/{projectSlug}/img/{imageId}
      console.log(
        `[${timestamp}] [${requestId}] Uploading file: ${file.originalname} as ${imageId} (${file.size} bytes)`,
      );

      const uploadResult = await storageService.uploadFile({
        orgSlug,
        projectSlug,
        imageId,
        buffer: file.buffer,
        contentType: file.mimetype,
        originalFilename: file.originalname,
      });

      if (!uploadResult.success) {
        const errorResponse: UploadFileResponse = {
          success: false,
          message: 'File upload failed',
          error: uploadResult.error || 'Storage service error',
        };
        return res.status(500).json(errorResponse);
      }

      // Prepare success response
      const successResponse: UploadFileResponse = {
        success: true,
        message: 'File uploaded successfully',
        data: {
          filename: uploadResult.filename,
          originalName: file.originalname,
          path: uploadResult.path,
          url: uploadResult.url,
          size: uploadResult.size,
          contentType: uploadResult.contentType,
          uploadedAt: timestamp,
        },
      };

      console.log(`[${timestamp}] [${requestId}] File uploaded successfully: ${uploadResult.url}`);

      return res.status(200).json(successResponse);
    } catch (error) {
      console.error(`[${timestamp}] [${requestId}] Unhandled error in upload endpoint:`, error);

      const errorResponse: UploadFileResponse = {
        success: false,
        message: 'File upload failed',
        error: error instanceof Error ? error.message : 'Unknown error occurred',
      };

      return res.status(500).json(errorResponse);
    }
  }),
);
