package com.ycwl.basic.integration.common.exception;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ycwl.basic.integration.common.response.CommonResponse;
import feign.Response;
import feign.codec.ErrorDecoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

@Slf4j
@Component
public class FeignErrorDecoder implements ErrorDecoder {
    
    private final ErrorDecoder defaultDecoder = new Default();
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public Exception decode(String methodKey, Response response) {
        log.warn("Feign调用失败, methodKey: {}, status: {}, reason: {}", 
                methodKey, response.status(), response.reason());

        try {
            if (response.body() != null) {
                String body = new String(response.body().asInputStream().readAllBytes(), StandardCharsets.UTF_8);
                log.warn("响应内容: {}", body);
                
                try {
                    CommonResponse<?> errorResponse = objectMapper.readValue(body, CommonResponse.class);
                    if (errorResponse.getCode() != null && !errorResponse.getCode().equals(200)) {
                        return new IntegrationException(
                            errorResponse.getCode(),
                            errorResponse.getMessage() != null ? errorResponse.getMessage() : "服务调用失败",
                            extractServiceName(methodKey)
                        );
                    }
                } catch (Exception e) {
                    log.warn("解析错误响应失败", e);
                }
            }
        } catch (IOException e) {
            log.error("读取响应体失败", e);
        }

        return new IntegrationException(
            response.status(),
            String.format("服务调用失败: %s", response.reason()),
            extractServiceName(methodKey)
        );
    }

    private String extractServiceName(String methodKey) {
        if (methodKey != null && methodKey.contains("#")) {
            return methodKey.substring(0, methodKey.indexOf("#"));
        }
        return "unknown";
    }
}