package com.dne.ems.exception;

import java.time.LocalDateTime;
import java.util.Map;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;

import com.dne.ems.dto.ErrorResponseDTO;
import lombok.extern.slf4j.Slf4j;

/**
 * 全局异常处理器，统一处理控制器层抛出的异常
 *
 * <p>处理流程：
 * <ol>
 *   <li>捕获控制器抛出的异常</li>
 *   <li>根据异常类型构建错误响应</li>
 *   <li>记录错误日志</li>
 *   <li>返回标准化的错误响应</li>
 * </ol>
 *
 * <p>已处理的异常类型：
 * <ul>
 *   <li>ResourceNotFoundException - 资源不存在(404)</li>
 *   <li>InvalidOperationException - 无效操作(400)</li>
 *   <li>Exception - 其他未处理异常(500)</li>
 * </ul>
 *
 * @author DNE开发团队
 * @version 1.0
 * @since 2024-03
 * @see com.dne.ems.exception.ResourceNotFoundException
 * @see com.dne.ems.exception.InvalidOperationException
 * @see com.dne.ems.dto.ErrorResponseDTO
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 处理资源不存在异常
     *
     * <p>当查询的资源不存在时抛出，返回404状态码
     *
     * @param ex 捕获的异常实例
     * @param request 当前Web请求
     * @return 包含错误详情的响应实体(404)
     * @see com.dne.ems.exception.ResourceNotFoundException
     */
    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<ErrorResponseDTO> handleResourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
        ErrorResponseDTO errorResponse = new ErrorResponseDTO(
                LocalDateTime.now(),
                HttpStatus.NOT_FOUND.value(),
                "Not Found",
                ex.getMessage(),
                request.getDescription(false).replace("uri=", ""));
        return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND);
    }

    /**
     * 处理无效操作异常
     *
     * <p>当业务规则不允许的操作时抛出，返回400状态码
     *
     * @param ex 捕获的异常实例
     * @param request 当前Web请求
     * @return 包含错误详情的响应实体(400)
     * @see com.dne.ems.exception.InvalidOperationException
     */
    @ExceptionHandler(InvalidOperationException.class)
    public ResponseEntity<ErrorResponseDTO> handleInvalidOperationException(InvalidOperationException ex, WebRequest request) {
        ErrorResponseDTO errorResponse = new ErrorResponseDTO(
                LocalDateTime.now(),
                HttpStatus.BAD_REQUEST.value(),
                "Bad Request",
                ex.getMessage(),
                request.getDescription(false).replace("uri=", ""));
        return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<?> handleGlobalException(Exception ex, WebRequest request) {
        log.error("捕获到全局未处理异常! 请求: {}", request.getDescription(false), ex);
        
        // 创建一个更详细的错误响应体
        Map<String, String> errorDetails = Map.of(
            "message", "服务器内部发生未知错误，请联系技术支持",
            "error", ex.getClass().getName(),
            "details", ex.getMessage()
        );
        
        return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
    }
} 