package cc.mrbird.febs.auth.configure;


import cn.cttic.crypto.bean.DecryptCodeBean;
import cn.cttic.crypto.bean.EncryptCodeBean;
import cn.cttic.crypto.bean.EncryptCrcBean;
import cn.cttic.crypto.service.SMCryptoService;
import cn.cttic.crypto.service.impl.SMCryptoServiceImpl;
import com.google.gson.Gson;
import com.ruoyi.common.core.domain.vo.TransportHeader;
import com.ruoyi.common.core.domain.vo.TransportRequest;
import com.ruoyi.common.core.domain.vo.TransportResponse;
import com.ruoyi.common.core.exception.TransportException;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;


public class TransportClient {

    private static final Logger logger = LoggerFactory.getLogger(TransportClient.class);

    // 配置参数
    private static final String API_ENDPOINT = "https://xcx.12328.cn:8086/min12328";
    private static final String PROVINCE_AREA_CODE = "500000"; // 行政区划代码
    private static final String BASE_AREA_CODE = "999999"; // 基础系统标识
    private static final DateTimeFormatter DATE_FORMATTER =
            DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
    private static final String encrypt_key = "8iot1blDJgNK36Do"; // 行政区划代码
    private static final String decrypt_key = "QLdQIASYMlT9SUUg";
    private final OkHttpClient httpClient = new OkHttpClient();
    private final Gson gson = new Gson();
    private final AtomicLong sequence = new AtomicLong(1);
    // 新增字段
    private long tokenExpirationTime;
    private static final long TOKEN_TTL = 24 * 60 * 60 * 1000; // 24小时毫秒数
    // 新增加密服务实例（在类顶部）
    private final SMCryptoService smCryptoService = new SMCryptoServiceImpl();


    public String sendRequest(String urlSuffix, String ipcType, Object bodyData) throws TransportException {
        try {

            // 1. 构建请求报文
            TransportRequest request = buildRequest(ipcType, bodyData);
            // 新增请求日志输出
            logger.info("完整请求报文:\n{}", gson.toJson(request));
            // 2. 发送HTTP请求
            String responseJson = postRequest(request, urlSuffix);
            System.out.println(responseJson);
            // 3. 处理响应
            TransportResponse response = parseResponse(responseJson);
            return handleResponse(response, urlSuffix);

        } catch (Exception e) {
            throw new TransportException("API请求失败: " + e.getMessage(), e);
        }
    }


    // 构建请求报文结构
    private TransportRequest buildRequest(String ipcType, Object bodyData) throws Exception {
        String plainBody = gson.toJson(bodyData);

        return new TransportRequest(
                new TransportHeader(
                        generateSerialNumber(),
                        PROVINCE_AREA_CODE,  // 省级标识
                        PROVINCE_AREA_CODE, // 部级标识+省级标识
                        BASE_AREA_CODE, // 部级标识
                        "V1",
                        ipcType,
                        LocalDateTime.now().format(DATE_FORMATTER),
                        calculateSM3(plainBody),
                        "0",
                        "",
                        null,
                        null
                ),
                encryptBody(plainBody)
        );
    }

    // 生成流水号（符合文档规范）
    private String generateSerialNumber() {

        // 2. 当前日期（必须8位）
        String datePart = LocalDateTime.now()
                .format(DateTimeFormatter.BASIC_ISO_DATE);

        // 3. 12位序列号（使用原子计数器示例）
        AtomicLong counter = new AtomicLong(1); // 实际应从数据库获取
        String sequence = String.format("%012d", counter.getAndIncrement() % 1000000000000L);

        return PROVINCE_AREA_CODE + datePart + sequence;
    }

    // SM3哈希计算
    public String calculateSM3(String data) {
        EncryptCrcBean encryptCrcBean = new EncryptCrcBean();
        encryptCrcBean.setPass(data);
        String cipherText_crc = smCryptoService.encryptCrc(encryptCrcBean);
        return cipherText_crc;
    }

    // SM4加密Body（ECB模式）
    public String encryptBody(String plainText) throws Exception {
        EncryptCodeBean encryptCodeBean = new EncryptCodeBean();
        encryptCodeBean.setSecretKey(encrypt_key);
        encryptCodeBean.setPass(plainText);
        String cipherText = smCryptoService.encrypt_Body(encryptCodeBean);
        return cipherText;
    }

    // SM4解密Body（ECB模式）
    public String decryptBody(String plainText) throws Exception {
        DecryptCodeBean encrypt2 = new DecryptCodeBean();
        encrypt2.setSecretKey(decrypt_key);
        encrypt2.setPass(plainText);
        String cipherText = smCryptoService.decrypt_Body(encrypt2);
        return cipherText;
    }

    // 发送HTTP请求
    private String postRequest(TransportRequest request, String urlSuffix) throws Exception {
        String json = gson.toJson(request);

        RequestBody body = RequestBody.create(json, MediaType.get("application/json"));
        Request httpRequest = new Request.Builder()
                .url(API_ENDPOINT + urlSuffix)
                .post(body)
                .build();

        try (Response response = httpClient.newCall(httpRequest).execute()) {
            if (!response.isSuccessful()) {
                throw new TransportException("HTTP错误: " + response.code());
            }
            return response.body().string();
        }
    }

    // 解析响应
    private TransportResponse parseResponse(String json) {
        return gson.fromJson(json, TransportResponse.class);
    }

    // 处理业务响应
    private String handleResponse(TransportResponse response, String urlSuffix) throws TransportException {
        TransportHeader header = response.getHeader();
        String currentToken = "";
        if (!"0000".equals(header.getCode())) {
            throw new TransportException("业务错误[" + header.getCode() + "]: "
                    + header.getMessage());
        }
        // 更新Token
        if (response.getBody() != null && response.getBody() != "") {
            try {
                TokenResponse tokenResponse = gson.fromJson(decryptBody(String.valueOf(response.getBody())), TokenResponse.class);
                currentToken = tokenResponse.getToken();
                logger.info(currentToken);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        logger.info("返回的response: \n{}", gson.toJson(response));
        return currentToken;
    }

    // 新增TokenResponse类
    public class TokenResponse {
        private String token;
        // getter/setter
        public String getToken() {
            return token;
        }

        public void setToken(String token) {
            this.token = token;
        }
    }

    // 初始化及使用示例
    public String getToken() {
        String token = "";
        TransportClient client = new TransportClient();
        Map<String, String> paramsMap = new HashMap<>();
        paramsMap.put("user", "admin");
        paramsMap.put("password", "ZDg3NDA5NjUyYmNk");
        // 1. 获取Token
        try {
            token = client.sendRequest("/sys/login", "YZ1001", paramsMap);

        } catch (TransportException e) {
            logger.info("身份验证失败: " + e.getMessage());
            throw new RuntimeException(e);
        }
        return token;
    }
}