package com.ruoyi.ai.service.impl;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.ruoyi.ai.service.IExchangeRateService;
import com.ruoyi.common.utils.http.OkHttpUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 汇率服务实现类
 *
 * @author system
 * @date 2025-01-XX
 */
@Service
@Slf4j
public class ExchangeRateServiceImpl implements IExchangeRateService {

    private final ObjectMapper objectMapper = new ObjectMapper();
    
    @Value("${exchange-rate.api-url:https://api.currencyfreaks.com/v2.0/rates/latest}")
    private String apiUrl;

    @Value("${exchange-rate.apikey:}")
    private String apikey;

    @Value("${exchange-rate.base-currency:USD}")
    private String baseCurrency;

    @Value("${exchange-rate.enabled:true}")
    private boolean enabled;

    @Value("${exchange-rate.fallback-rate-jinsha:90}")
    private BigDecimal fallbackRateJinSha;

    @Value("${exchange-rate.fallback-rate-kada:60}")
    private BigDecimal fallbackRateKaDa;

    @Value("${exchange-rate.fallback-rate-php:90}")
    private BigDecimal fallbackRatePHP;

    @Override
    public BigDecimal getExchangeRate(String fromCurrency, String toCurrency) throws Exception {
        if (!enabled) {
            log.warn("汇率服务未启用，使用默认汇率");
            return getFallbackRate(toCurrency);
        }

        try {
            // 构建请求URL - 使用 CurrencyFreaks Rates Latest Endpoint
            String url = buildApiUrl();
            
            // 构建请求
            Request request = new Request.Builder()
                    .url(url)
                    .get()
                    .build();

            // 发送请求
            Response response = OkHttpUtils.newCall(request).execute();
            ResponseBody body = response.body();

            if (response.isSuccessful() && body != null) {
                String responseBody = body.string();
                log.debug("汇率API响应: {}", responseBody);
                
                // 解析响应 - CurrencyFreaks Rates Latest Endpoint 响应格式
                RatesResponse ratesResponse = objectMapper.readValue(responseBody, RatesResponse.class);
                
                if (ratesResponse != null && ratesResponse.getRates() != null) {
                    BigDecimal rate = calculateRate(ratesResponse, fromCurrency, toCurrency);
                    if (rate != null && rate.compareTo(BigDecimal.ZERO) > 0) {
                        log.info("成功获取汇率 {} -> {}: {}", fromCurrency, toCurrency, rate);
                        return rate;
                    }
                }
            } else {
                log.warn("汇率API请求失败，状态码: {}", response.code());
                if (body != null) {
                    log.warn("响应内容: {}", body.string());
                }
            }
        } catch (Exception e) {
            log.error("获取汇率失败，使用备用汇率: {}", e.getMessage(), e);
        }

        // 如果API调用失败，使用备用汇率
        return getFallbackRate(toCurrency);
    }

    @Override
    public BigDecimal convertAmount(BigDecimal amount, String fromCurrency, String toCurrency) throws Exception {
        if (amount == null) {
            throw new IllegalArgumentException("金额不能为空");
        }

        if (!enabled) {
            log.warn("汇率服务未启用，使用默认汇率计算");
            BigDecimal rate = getFallbackRate(toCurrency);
            // 返回完整精度，不限制小数位
            return amount.multiply(rate);
        }

        try {
            // 构建请求URL - 使用 CurrencyFreaks Rates Latest Endpoint
            String url = buildApiUrl();
            
            // 构建请求
            Request request = new Request.Builder()
                    .url(url)
                    .get()
                    .build();

            // 发送请求
            Response response = OkHttpUtils.newCall(request).execute();
            ResponseBody body = response.body();

            if (response.isSuccessful() && body != null) {
                String responseBody = body.string();
//                log.debug("汇率API响应: {}", responseBody);

                // 解析响应 - CurrencyFreaks Rates Latest Endpoint 响应格式
                RatesResponse ratesResponse = objectMapper.readValue(responseBody, RatesResponse.class);
                
                if (ratesResponse != null && ratesResponse.getRates() != null) {
                    BigDecimal rate = calculateRate(ratesResponse, fromCurrency, toCurrency);
                    if (rate != null && rate.compareTo(BigDecimal.ZERO) > 0) {
                        BigDecimal convertedAmount = amount.multiply(rate);
                        log.info("成功转换金额 {} {} -> {} {}: {}", 
                                amount, fromCurrency, convertedAmount, toCurrency, rate);
                        // 返回完整精度，不限制小数位
                        return convertedAmount;
                    }
                }
            } else {
                log.warn("汇率API请求失败，状态码: {}", response.code());
                if (body != null) {
                    log.warn("响应内容: {}", body.string());
                }
            }
        } catch (Exception e) {
            log.error("转换金额失败，使用备用汇率计算: {}", e.getMessage(), e);
        }

        // 如果API调用失败，使用备用汇率计算（不限制小数位）
        BigDecimal rate = getFallbackRate(toCurrency);
        return amount.multiply(rate);
    }

    /**
     * 构建API URL - 使用 CurrencyFreaks Rates Latest Endpoint
     */
    private String buildApiUrl() {
        if (apiUrl.contains("currencyfreaks.com") && apiUrl.contains("/rates/latest")) {
            // 使用 CurrencyFreaks Rates Latest Endpoint 格式
            // https://api.currencyfreaks.com/v2.0/rates/latest?apikey=YOUR_APIKEY&base=USD
            StringBuilder urlBuilder = new StringBuilder(apiUrl);
            urlBuilder.append("?apikey=").append(apikey);
            urlBuilder.append("&base=").append(baseCurrency.toUpperCase());
            return urlBuilder.toString();
        } else {
            // 兼容其他API格式（向后兼容）
            return apiUrl;
        }
    }

    /**
     * 根据汇率响应计算 fromCurrency 到 toCurrency 的汇率
     */
    private BigDecimal calculateRate(RatesResponse ratesResponse, String fromCurrency, String toCurrency) {
        String base = ratesResponse.getBase();
        java.util.Map<String, String> rates = ratesResponse.getRates();
        
        if (rates == null || rates.isEmpty()) {
            log.warn("汇率响应中 rates 为空");
            return null;
        }

        String fromUpper = fromCurrency.toUpperCase();
        String toUpper = toCurrency.toUpperCase();
        String baseUpper = base.toUpperCase();

        // 如果源货币就是基准货币
        if (baseUpper.equals(fromUpper)) {
            String toRateStr = rates.get(toUpper);
            if (toRateStr != null) {
                try {
                    return new BigDecimal(toRateStr);
                } catch (NumberFormatException e) {
                    log.error("无法解析目标货币 {} 的汇率: {}", toUpper, toRateStr);
                    return null;
                }
            } else {
                log.warn("未找到目标货币 {} 的汇率", toUpper);
                return null;
            }
        }

        // 如果目标货币就是基准货币
        if (baseUpper.equals(toUpper)) {
            String fromRateStr = rates.get(fromUpper);
            if (fromRateStr != null) {
                try {
                    // 如果目标货币是基准货币，汇率是 1 / fromRate
                    BigDecimal fromRate = new BigDecimal(fromRateStr);
                    if (fromRate.compareTo(BigDecimal.ZERO) > 0) {
                        return BigDecimal.ONE.divide(fromRate, 10, RoundingMode.HALF_UP);
                    }
                } catch (NumberFormatException e) {
                    log.error("无法解析源货币 {} 的汇率: {}", fromUpper, fromRateStr);
                    return null;
                }
            } else {
                log.warn("未找到源货币 {} 的汇率", fromUpper);
                return null;
            }
        }

        // 两个货币都不是基准货币，需要计算
        String fromRateStr = rates.get(fromUpper);
        String toRateStr = rates.get(toUpper);

        if (fromRateStr == null) {
            log.warn("未找到源货币 {} 的汇率", fromUpper);
            return null;
        }
        if (toRateStr == null) {
            log.warn("未找到目标货币 {} 的汇率", toUpper);
            return null;
        }

        try {
            BigDecimal fromRate = new BigDecimal(fromRateStr);
            BigDecimal toRate = new BigDecimal(toRateStr);
            
            if (fromRate.compareTo(BigDecimal.ZERO) > 0) {
                // 汇率 = toRate / fromRate
                // 例如：base=USD, from=CNY, to=PHP
                // USD->CNY = fromRate, USD->PHP = toRate
                // CNY->PHP = toRate / fromRate
                return toRate.divide(fromRate, 10, RoundingMode.HALF_UP);
            }
        } catch (NumberFormatException e) {
            log.error("无法解析汇率: from={}, to={}", fromRateStr, toRateStr);
            return null;
        }

        return null;
    }

    /**
     * 获取备用汇率（当API调用失败时使用）
     */
    private BigDecimal getFallbackRate(String toCurrency) {
        // 根据目标货币返回不同的备用汇率
        if ("PHP".equalsIgnoreCase(toCurrency)) {
            // PHP比索，使用配置的PHP备用汇率
            log.warn("使用PHP备用汇率: {}", fallbackRatePHP);
            return fallbackRatePHP;
        }
        // 其他货币可以扩展，默认使用PHP的备用汇率
        log.warn("未配置货币 {} 的备用汇率，使用PHP默认汇率 {}", toCurrency, fallbackRatePHP);
        return fallbackRatePHP;
    }

    /**
     * CurrencyFreaks Rates Latest Endpoint 响应对象
     */
    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    static class RatesResponse {
        @JsonProperty("date")
        private String date;
        
        @JsonProperty("base")
        private String base;
        
        @JsonProperty("rates")
        private java.util.Map<String, String> rates;
    }
}
