import { Request, Response, NextFunction } from 'express';
import Joi from 'joi';
import { v4 as uuidv4 } from 'uuid';

// Document upload validation schema
const documentUploadSchema = Joi.object({
  title: Joi.string().min(1).max(255).optional(),
  description: Joi.string().max(1000).optional(),
});

export const validateDocumentUpload = (
  req: Request,
  res: Response,
  next: NextFunction
): void => {
  const { error } = documentUploadSchema.validate(req.body);
  
  if (error) {
    res.status(400).json({
      success: false,
      error: 'Validation failed',
      details: error.details.map(detail => detail.message),
    });
    return;
  }
  
  next();
};

// UUID validation middleware
export const validateUUID = (paramName: string = 'id') => {
  return (req: Request, res: Response, next: NextFunction): void => {
    const id = req.params[paramName];
    
    if (!id) {
      res.status(400).json({
        success: false,
        error: 'Missing required parameter',
        details: `${paramName} parameter is required`,
        correlationId: req.headers['x-correlation-id'] || 'unknown'
      });
      return;
    }

    // UUID v4 validation regex
    const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
    
    if (!uuidRegex.test(id)) {
      res.status(400).json({
        success: false,
        error: 'Invalid UUID format',
        details: `${paramName} must be a valid UUID v4 format`,
        correlationId: req.headers['x-correlation-id'] || 'unknown',
        receivedValue: id
      });
      return;
    }
    
    next();
  };
};

// Request correlation ID middleware
export const addCorrelationId = (req: Request, res: Response, next: NextFunction): void => {
  // Use existing correlation ID from headers or generate new one
  const correlationId = req.headers['x-correlation-id'] as string || uuidv4();
  
  // Add correlation ID to request object for use in controllers
  req.correlationId = correlationId;
  
  // Add correlation ID to response headers
  res.setHeader('x-correlation-id', correlationId);
  
  next();
};

// Extend Express Request to include correlationId
declare global {
  namespace Express {
    interface Request {
      correlationId?: string;
    }
  }
}

// Feedback validation schema
const feedbackSchema = Joi.object({
  rating: Joi.number().min(1).max(5).required(),
  comment: Joi.string().max(1000).optional(),
});

export const validateFeedback = (
  req: Request,
  res: Response,
  next: NextFunction
): void => {
  const { error } = feedbackSchema.validate(req.body);
  
  if (error) {
    res.status(400).json({
      success: false,
      error: 'Validation failed',
      details: error.details.map(detail => detail.message),
      correlationId: req.correlationId || 'unknown'
    });
    return;
  }
  
  next();
};

// Regeneration validation schema
const regenerationSchema = Joi.object({
  feedbackId: Joi.string().required(),
});

export const validateRegeneration = (
  req: Request,
  res: Response,
  next: NextFunction
): void => {
  const { error } = regenerationSchema.validate(req.body);
  
  if (error) {
    res.status(400).json({
      success: false,
      error: 'Validation failed',
      details: error.details.map(detail => detail.message),
    });
    return;
  }
  
  next();
}; 