package com.test.bijihoudaun.common.advice;

import com.test.bijihoudaun.common.exception.BaseException;
import com.test.bijihoudaun.common.exception.RegistrationException;
import com.test.bijihoudaun.common.response.R;
import com.test.bijihoudaun.common.response.ResultCode;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authorization.AuthorizationDeniedException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import java.util.List;
import java.util.stream.Collectors;

@RestControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(BaseException.class)
    public R<Void> handleBaseException(BaseException e, HttpServletRequest request) {
        log.warn("Business exception at {}: {}", request.getRequestURI(), e.getMessage());
        return R.fail(e.getResultCode().getCode(), e.getMessage());
    }

    @ExceptionHandler(RegistrationException.class)
    public R<String> handleRegistrationException(RegistrationException e, HttpServletRequest request) {
        log.warn("Registration failed at {}: {}", request.getRequestURI(), e.getMessage());
        return R.fail(e.getMessage());
    }

    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public R<String> handleFileSizeLimitExceeded(HttpServletRequest request) {
        log.warn("File size exceeded at {}", request.getRequestURI());
        return R.fail("文件大小超过限制");
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public R<List<String>> handleMethodArgumentNotValidException(MethodArgumentNotValidException e, HttpServletRequest request) {
        List<String> errors = e.getBindingResult().getFieldErrors()
                .stream()
                .map(FieldError::getDefaultMessage)
                .collect(Collectors.toList());
        log.warn("Validation failed at {}: {}", request.getRequestURI(), errors.get(0));
        return R.fail(ResultCode.VALIDATE_FAILED.getCode(), errors.get(0));
    }

    @ExceptionHandler(BindException.class)
    public R<List<String>> handleBindException(BindException e, HttpServletRequest request) {
        List<String> errors = e.getBindingResult().getFieldErrors()
                .stream()
                .map(FieldError::getDefaultMessage)
                .collect(Collectors.toList());
        log.warn("Bind exception at {}: {}", request.getRequestURI(), errors.get(0));
        return R.fail(ResultCode.VALIDATE_FAILED.getCode(), errors.get(0));
    }

    @ExceptionHandler(org.springframework.http.converter.HttpMessageNotReadableException.class)
    public R<String> handleHttpMessageNotReadableException(HttpServletRequest request) {
        log.warn("Invalid request body at {}", request.getRequestURI());
        return R.fail(ResultCode.VALIDATE_FAILED.getCode(), "请求参数格式不正确");
    }

    @ExceptionHandler(IllegalArgumentException.class)
    public R<Void> handleIllegalArgumentException(IllegalArgumentException e, HttpServletRequest request) {
        log.warn("Illegal argument at {}: {}", request.getRequestURI(), e.getMessage());
        return R.fail(ResultCode.VALIDATE_FAILED.getCode(), "参数错误");
    }

    // 修复：添加权限拒绝异常处理
    @ExceptionHandler(AuthorizationDeniedException.class)
    public R<Void> handleAuthorizationDeniedException(AuthorizationDeniedException e, HttpServletRequest request) {
        log.warn("Access denied at {}: {}", request.getRequestURI(), e.getMessage());
        return R.fail(ResultCode.FORBIDDEN.getCode(), "无权操作，需要管理员权限");
    }

    @ExceptionHandler(Exception.class)
    public R<Void> handleException(Exception e, HttpServletRequest request) {
        log.error("Unexpected error at {} - Error type: {}", request.getRequestURI(), e.getClass().getSimpleName());
        return R.fail(ResultCode.FAILED.getCode(), "系统繁忙，请稍后再试");
    }

    // 修复：处理 IllegalStateException（getWriter() 已调用等问题）
    @ExceptionHandler(IllegalStateException.class)
    public R<Void> handleIllegalStateException(IllegalStateException e, HttpServletRequest request) {
        log.warn("Illegal state at {}: {}", request.getRequestURI(), e.getMessage());
        // 如果是图片预览相关请求，可能是响应已经提交
        if (request.getRequestURI().contains("/api/images/preview")) {
            // 响应可能已经提交，直接返回 null，避免再次写入响应
            return null;
        }
        return R.fail(ResultCode.FAILED.getCode(), "请求处理失败");
    }
}
