import logger from '../utils/logger.js';
import { z } from 'zod';

export const errorHandler = (err, req, res, next) => {
  const requestId = req.id;
  const timestamp = new Date().toISOString();
  
  // Validation error from Zod
  if (err instanceof z.ZodError) {
    logger.warn({
      message: 'Validation error',
      request_id: requestId,
      method: req.method,
      path: req.path,
      errors: err.errors
    });
    
    return res.status(400).json({
      status: 'error',
      error: {
        code: 'BAD_REQUEST',
        message: 'Validation failed',
        details: err.errors.map(e => ({
          field: e.path.join('.'),
          message: e.message
        }))
      },
      meta: { timestamp, request_id: requestId }
    });
  }
  
  // JSON parsing error
  if (err instanceof SyntaxError && 'body' in err) {
    logger.warn({
      message: 'JSON parse error',
      request_id: requestId,
      method: req.method,
      path: req.path,
      error: err.message
    });
    
    return res.status(400).json({
      status: 'error',
      error: {
        code: 'BAD_REQUEST',
        message: 'Invalid JSON in request body'
      },
      meta: { timestamp, request_id: requestId }
    });
  }
  
  // Custom API error
  if (err.status && err.code) {
    logger.warn({
      message: 'API error',
      request_id: requestId,
      status: err.status,
      code: err.code,
      error: err.message
    });
    
    return res.status(err.status).json({
      status: 'error',
      error: {
        code: err.code,
        message: err.message,
        details: err.details || {}
      },
      meta: { timestamp, request_id: requestId }
    });
  }
  
  // Database error
  if (err.name === 'ClientError' || err.name === 'QueryResultError') {
    logger.error({
      message: 'Database error',
      request_id: requestId,
      method: req.method,
      path: req.path,
      error: err.message,
      code: err.code
    });
    
    // Handle specific constraint violations
    if (err.code === '23503') {
      // Foreign key violation
      return res.status(422).json({
        status: 'error',
        error: {
          code: 'UNPROCESSABLE_ENTITY',
          message: 'Invalid reference to related resource'
        },
        meta: { timestamp, request_id: requestId }
      });
    }
    
    if (err.code === '23505') {
      // Unique constraint violation
      return res.status(409).json({
        status: 'error',
        error: {
          code: 'CONFLICT',
          message: 'Resource already exists'
        },
        meta: { timestamp, request_id: requestId }
      });
    }
    
    // Generic DB error
    return res.status(500).json({
      status: 'error',
      error: {
        code: 'INTERNAL_SERVER_ERROR',
        message: 'Database operation failed'
      },
      meta: { timestamp, request_id: requestId }
    });
  }
  
  // Unhandled error
  logger.error({
    message: 'Unhandled error',
    request_id: requestId,
    method: req.method,
    path: req.path,
    error: err.message,
    stack: err.stack
  });
  
  res.status(500).json({
    status: 'error',
    error: {
      code: 'INTERNAL_SERVER_ERROR',
      message: 'Internal server error'
    },
    meta: { timestamp, request_id: requestId }
  });
};
