package com.yc.ship.module.trade.utils;

import cn.hutool.extra.pinyin.PinyinUtil;
import com.alibaba.fastjson.JSONObject;
import com.anji.captcha.util.MD5Util;
import com.yc.ship.framework.common.pojo.CommonResult;
import com.yc.ship.framework.common.util.http.HttpUtils;
import com.yc.ship.module.infra.api.config.ConfigApi;
import com.yc.ship.module.trade.api.insurance.dto.InsuranceApplyReqDTO;
import com.yc.ship.module.trade.api.insurance.dto.InsuranceCancelReqDTO;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import static com.yc.ship.framework.common.exception.util.ServiceExceptionUtil.exception0;

/**
 * 阳光保险接口工具类
 */
@Slf4j
@Component
public class InsuranceUtil {

//    public final String HOST = "https://lbb-admin.anyitech.ltd"; //测试域名
//
//    public final String VALIDATE_URL = "/policy/validateJson.do"; // 请求校验接口
//
//    public final String RECEIVE_URL = "/policy/receiveJson.do"; // JSON投/退保接口
//
//    public final String QUERY_URL = "/policy/querystatus.do"; // 保单状态查询接口
//
//    public final String APPID = "123456";   // appId
//
//    public final String KEY = "goldpalm"; // key

    private final Integer VALIDATE_LEVEL = 0; //校验级别，其值有 0/1

    @Resource
    private ConfigApi configApi;

    /**
     * REST模板
     */
    private RestTemplate restTemplate;

    /**
     * 构造函数
     */
    public InsuranceUtil() {
        this.restTemplate = new RestTemplate();
    }



    /**
     * 发送投保请求
     * 将投保请求发送到阳光系统
     *
     * @param request 投保请求
     * @return 投保响应
     */
    public CommonResult sendInsuranceApply(InsuranceApplyReqDTO request) {
        String HOST = configApi.getConfigValueByKey("insuranceConfig.host");
        String RECEIVE_URL = configApi.getConfigValueByKey("insuranceConfig.receive_url");
        String VALIDATE_URL = configApi.getConfigValueByKey("insuranceConfig.validate_url");
        String APPID = configApi.getConfigValueByKey("insuranceConfig.app_id");
        String KEY = configApi.getConfigValueByKey("insuranceConfig.key");
        try {
            String reqJson = JSONObject.toJSONString(request);
            String sign = SignUtil.generateMD5Sign(APPID, reqJson, KEY);

            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.add("appId", APPID);
            params.add("req", reqJson);
            params.add("sign", sign);

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

            HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(params, headers);

            log.info("发送投保请求到阳光系统: {}", HOST + RECEIVE_URL);
            log.info("请求参数: appId={}, req={}, sign={}", APPID, reqJson, sign);

            // 发送请求并获取响应
            ResponseEntity<byte[]> response = restTemplate.exchange(
                    HOST + RECEIVE_URL,
                    HttpMethod.POST,
                    entity,
                    byte[].class
            );

            log.info("阳光系统响应状态码: {}", response.getStatusCode());

            // 手动处理响应字节流，确保使用UTF-8编码
            byte[] responseBytes = response.getBody();
            String responseBody = null;
            if (responseBytes != null) {
                try {
                    responseBody = new String(responseBytes, "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    log.error("解析响应内容编码失败", e);
                    responseBody = new String(responseBytes);
                }
            }

            log.info("阳光系统响应内容: {}", responseBody);
            JSONObject responseBodyJson = JSONObject.parseObject(responseBody);

            if (response.getStatusCode() == HttpStatus.OK) {
                String status = responseBodyJson.getString("status");
                if ("FAIL".equals(status)) {
                    return CommonResult.error(500, "阳光系统投保返回错误: " + response.getStatusCode() + responseBody);
                } else {
                    return CommonResult.success(responseBody);
                }
            } else {
                return CommonResult.error(500, "阳光系统投保返回错误: " + response.getStatusCode() + responseBody);
            }

        } catch (Exception e) {
            log.error("发送投保请求失败", e);
            return CommonResult.error(500, "发送投保请求失败: " + e.getMessage());
        }
    }

    /**
     * 校验保险请求
     * 在调用投保接口前，为了提高投保成功率，可先调用校验接口，检查客户系统组织的请求是否符合预期
     *
     * @param request 投保请求
     * @return 校验响应
     */
    public CommonResult validateInsuranceRequest(InsuranceApplyReqDTO request) {
        String HOST = configApi.getConfigValueByKey("insuranceConfig.host");
        String VALIDATE_URL = configApi.getConfigValueByKey("insuranceConfig.validate_url");
        String APPID = configApi.getConfigValueByKey("insuranceConfig.app_id");
        String KEY = configApi.getConfigValueByKey("insuranceConfig.key");
        try {
            String reqJson = JSONObject.toJSONString(request);

            // 构建校验请求参数
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.add("appId", APPID);
            params.add("req", reqJson);
            params.add("validateLevel", VALIDATE_LEVEL.toString());

            // 生成签名
            Map<String, String> signParams = new HashMap<>();
            signParams.put("appId", APPID);
            signParams.put("req", reqJson);
            signParams.put("validateLevel", VALIDATE_LEVEL.toString());
            String sign = SignUtil.generateMD5Sign(signParams, KEY);
            params.add("sign", sign);

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

            HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(params, headers);

            // 校验接口地址
            String validateApiUrl = HOST + VALIDATE_URL;

            log.info("发送校验请求到阳光系统: {}", validateApiUrl);
            log.info("请求参数: appId={}, validateLevel={}, sign={}", APPID, VALIDATE_LEVEL, sign);

            // 发送请求并获取响应
            ResponseEntity<byte[]> response = restTemplate.exchange(
                    validateApiUrl,
                    HttpMethod.POST,
                    entity,
                    byte[].class
            );

            log.info("阳光系统校验响应状态码: {}", response.getStatusCode());
            // 手动处理响应字节流，确保使用UTF-8编码
            byte[] responseBytes = response.getBody();
            String responseBody = null;
            if (responseBytes != null) {
                try {
                    responseBody = new String(responseBytes, "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    log.error("解析响应内容编码失败", e);
                    responseBody = new String(responseBytes);
                }
            }

            log.info("阳光系统校验响应内容: {}", responseBody);
            JSONObject responseBodyJson = JSONObject.parseObject(responseBody);
            if ("SUCCESS".equals(responseBodyJson.getString("status"))) {
                return CommonResult.success(responseBody);
            } else {
                // 响应失败，返回错误信息
                return CommonResult.error(500, "阳光系统校验返回错误: " + response.getStatusCode() + responseBody);
            }
        } catch (Exception e) {
            log.error("发送校验请求失败", e);
            throw exception0(500, "发送校验请求失败: " + e.getMessage(), e);
        }
    }

    /**
     * 发送退保请求
     * 将退保请求发送到阳光系统
     *
     * @param request 退保请求
     * @return 退保响应
     */
    public CommonResult sendInsuranceCancel(InsuranceCancelReqDTO request) {
        String HOST = configApi.getConfigValueByKey("insuranceConfig.host");
        String RECEIVE_URL = configApi.getConfigValueByKey("insuranceConfig.receive_url");
        String APPID = configApi.getConfigValueByKey("insuranceConfig.app_id");
        String KEY = configApi.getConfigValueByKey("insuranceConfig.key");
        try {
            String reqJson = JSONObject.toJSONString(request);
            String sign = SignUtil.generateMD5Sign(APPID, reqJson, KEY);

            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.add("appId", APPID);
            params.add("req", reqJson);
            params.add("sign", sign);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<>(params, headers);
            log.error("发送退保请求到阳光系统: {}", HOST + RECEIVE_URL);
            log.error("请求参数: appId={}, req={}, sign={}", APPID, reqJson, sign);
            // 发送请求并获取响应
            ResponseEntity<byte[]> response = restTemplate.exchange(
                    HOST + RECEIVE_URL,
                    HttpMethod.POST,
                    entity,
                    byte[].class
            );
            log.error("阳光系统响应状态码: {}", response.getStatusCode());
            // 手动处理响应字节流，确保使用UTF-8编码
            byte[] responseBytes = response.getBody();
            String responseBody = null;
            if (responseBytes != null) {
                responseBody = new String(responseBytes, StandardCharsets.UTF_8);
            }
            log.error("阳光系统响应内容: {}", responseBody);
            JSONObject responseBodyJson = JSONObject.parseObject(responseBody);
            if (response.getStatusCode() == HttpStatus.OK) {
                String status = responseBodyJson.getString("status");
                if ("FAIL".equals(status)) {
                    return CommonResult.error(500, "阳光系统退保返回错误: " + response.getStatusCode() + responseBody);
                } else {
                    return CommonResult.success(responseBody);
                }
            } else {
                return CommonResult.error(500, "阳光系统退保返回错误: " + response.getStatusCode() + responseBody);
            }

        } catch (Exception e) {
            log.error("发送退保请求失败", e);
            return CommonResult.error(500, "发送退保请求失败: " + e.getMessage());
        }
    }

    public CommonResult queryInsurance(String orderNo) {
        String QUERY_URL = configApi.getConfigValueByKey("insuranceConfig.query_url");
        String HOST = configApi.getConfigValueByKey("insuranceConfig.host");
        String APPID = configApi.getConfigValueByKey("insuranceConfig.app_id");
        String KEY = configApi.getConfigValueByKey("insuranceConfig.key");
        try {
            if(StringUtils.isBlank(orderNo)) {
                return CommonResult.error(500, "订单号不能为空");
            }
            Map<String, String> request = new LinkedHashMap<>();
            request.put("appId", APPID);
            request.put("externalOrderNo", orderNo);
            request.put("key", KEY);
            String sign = MD5Util.md5(APPID + orderNo + KEY);

            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.add("appId", APPID);
            params.add("externalOrderNo", orderNo);
            params.add("sign", sign);
            String url = HOST + QUERY_URL + "?appId=" + APPID + "&externalOrderNo=" + orderNo + "&sign=" + sign;
            log.error("发送查询请求到阳光系统: {}", url);
            String s = HttpUtils.get(url, null);
            log.error("阳光系统查询响应内容: {}", s);
            //{"phase":"INSURE","externalOrderNo":"tys-20261001-YC-14",
            // "paiedAmount":"10.00","total":"1","insuredCount":"1","insureProcessingCount":"0",
            // "cancelledCount":"0","cancelProcessingCount":"0","refundedAmount":"0.0",
            // "cipher":"26e2e422d370653274ee74ef3edc7f93","policies":[{"externalPolicyNumber":"2037220248460828673",
            // "service":"applyTeam","status":"SUCCESS","msg":"投保成功","policyNo":"HW61927008L7JB7J8Q00"}]}
            return CommonResult.success(s);
        } catch (Exception e) {
            log.error("发送查询请求失败", e);
            return CommonResult.error(500, "发送查询请求失败: " + e.getMessage());
        }
    }

    public CommonResult queryInsuranceNew(String orderNo,Long orderId) {
        String QUERY_URL = configApi.getConfigValueByKey("insuranceConfig.query_url");
        String HOST = configApi.getConfigValueByKey("insuranceConfig.host");
        String APPID = configApi.getConfigValueByKey("insuranceConfig.app_id");
        String KEY = configApi.getConfigValueByKey("insuranceConfig.key");
        try {
            if(StringUtils.isBlank(orderNo)) {
                return CommonResult.error(500, "订单号不能为空");
            }
            Map<String, String> request = new LinkedHashMap<>();
            request.put("appId", APPID);
            request.put("externalOrderNo", orderNo);
            request.put("key", KEY);
            String sign = MD5Util.md5(APPID + orderNo + KEY);

            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.add("appId", APPID);
            params.add("externalOrderNo", orderNo);
            params.add("sign", sign);
            String url = HOST + QUERY_URL + "?appId=" + APPID + "&externalOrderNo=" + orderNo + "&sign=" + sign;
            log.error(orderNo+"发送查询请求到阳光系统: {}", url);
            String s = HttpUtils.get(url, null);
            log.error(orderNo+"阳光系统查询响应内容: {}", s);

            return CommonResult.success(s);
        } catch (Exception e) {
            log.error("发送查询请求失败", e);
            return CommonResult.error(500, "发送查询请求失败: " + e.getMessage());
        }
    }

    public static void main(String[] args) {
        InsuranceUtil insuranceUtil = new InsuranceUtil();
        CommonResult commonResult = insuranceUtil.queryInsurance("2039500964189302785");
        System.out.println(commonResult);


    }
}
