package com.qqchen.deploy.backend.framework.handler;

import com.qqchen.deploy.backend.framework.api.Response;
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
import com.qqchen.deploy.backend.framework.exception.BusinessException;
import com.qqchen.deploy.backend.framework.exception.SystemException;
import com.qqchen.deploy.backend.framework.exception.UniqueConstraintException;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.security.SignatureException;

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    @Autowired
    private MessageSource messageSource;

    @ExceptionHandler(BusinessException.class)
    public Response<?> handleBusinessException(BusinessException e) {
        log.warn("Business error occurred: {}", e.getErrorCode().getMessageKey(), e);
        return Response.error(e.getErrorCode());
    }

    @ExceptionHandler(SystemException.class)
    public Response<?> handleSystemException(SystemException e) {
        log.error("System error occurred", e);
        return Response.error(ResponseCode.ERROR);
    }

    @ExceptionHandler(BadCredentialsException.class)
    public Response<?> handleBadCredentialsException(BadCredentialsException e) {
        log.warn("Login failed: Bad credentials", e);
        return Response.error(ResponseCode.LOGIN_ERROR);
    }

    @ExceptionHandler(ExpiredJwtException.class)
    public Response<?> handleExpiredJwtException(ExpiredJwtException e) {
        log.warn("JWT token expired", e);
        return Response.error(ResponseCode.JWT_EXPIRED);
    }

    @ExceptionHandler({SignatureException.class, MalformedJwtException.class})
    public Response<?> handleInvalidJwtException(Exception e) {
        log.warn("Invalid JWT token", e);
        return Response.error(ResponseCode.JWT_INVALID);
    }

    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    public Response<?> handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e) {
        String message = String.format("参数[%s]类型错误, 期望类型: %s, 实际值: %s",
            e.getName(),
            e.getRequiredType().getSimpleName(),
            e.getValue());
        log.warn("Parameter type mismatch: {}", message);
        return Response.error(ResponseCode.INVALID_PARAM, message);
    }

    @ExceptionHandler(NoHandlerFoundException.class)
    public Response<?> handleNoHandlerFoundException(NoHandlerFoundException e) {
        String message = String.format("接口不存在: %s %s", e.getHttpMethod(), e.getRequestURL());
        log.warn("API not found: {}", message);
        return Response.error(ResponseCode.NOT_FOUND, message);
    }

    @ExceptionHandler(Exception.class)
    public Response<?> handleException(Exception e) {
        log.error("Unexpected error occurred", e);
        return Response.error(ResponseCode.ERROR);
    }

    @ExceptionHandler(UniqueConstraintException.class)
    public Response<?> handleUniqueConstraintException(UniqueConstraintException e) {
        String message = messageSource.getMessage(e.getErrorCode().getMessageKey(), new Object[] {e.getField(), e.getValue()}, LocaleContextHolder.getLocale());
        log.warn("Unique constraint violation: {} = {}", e.getField(), e.getValue());
        return Response.error(e.getErrorCode(), message);
    }
} 