package org.dromara.zjk.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.util.ReflectUtil;
import com.alibaba.fastjson2.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R;

import org.dromara.zjk.annualInspection.annualInspectionAudit.service.IZjkAnnualInspectionService;
import org.dromara.zjk.expert.expertRecommend.service.IZjkExpertRecommendService;
import org.dromara.zjk.service.IZjkExpertService;
import org.dromara.zjk.service.IZjkInvoiceService;
import org.dromara.zjk.service.IZjkProductService;
import org.dromara.zjk.service.ZjkPointService;
import org.dromara.zjk.zwy.client.HmacClient;
import org.dromara.zjk.zwy.domain.HmacCheckRequest;
import org.dromara.zjk.zwy.utils.ObjectHashGenerator;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.nio.charset.StandardCharsets;
import java.util.*;


/**
 * zj
 * 2025.6.23
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/hmac")
@Slf4j
public class SysHmacController {


    private final HmacClient hmacClient;

    private final IZjkProductService zjkProductService;

    private final IZjkExpertRecommendService zjkExpertRecommendService;

    private final IZjkInvoiceService zjkInvoiceService;

    private final IZjkExpertService zjkExpertService;

    private final IZjkAnnualInspectionService zjkAnnualInspectionService;

    private final ZjkPointService zjkPointService;

    @SaIgnore
    @PostMapping("/verifyHmac")
    public R<Map<String, Object>> verifyHmac(@RequestBody HmacCheckRequest request) {
        Object bizObj;

        switch (request.getBizType()) {
            case "product":
                bizObj = zjkProductService.queryById(request.getId());
                break;
            case "expertRecommend":
                bizObj = zjkExpertRecommendService.queryById(request.getId());
                break;
            case "invoice":
                bizObj = zjkInvoiceService.queryById(request.getId());
                break;
            case "expert":
                bizObj = zjkExpertService.getExpertObjectById(request.getId());
                break;
            case "ZjkAnnualInspection":
                bizObj = zjkAnnualInspectionService.queryById(request.getId());
                break;
            case "point":
                bizObj = zjkPointService.queryHmacById(request.getId());
                break;
            default:
                return R.fail("不支持的业务类型: " + request.getBizType());
        }

        if (bizObj == null) {
            return R.fail("数据不存在");
        }

        // 2. 计算拼接字符串
        String concatenatedValues;
        if (request.getFields() == null || request.getFields().isEmpty()) {
            concatenatedValues = ObjectHashGenerator.generateHash(bizObj);
        } else {
            Map<String, Object> fieldMap = new LinkedHashMap<>();
            for (String field : request.getFields()) {
                Object val = ReflectUtil.getFieldValue(bizObj, field);
                fieldMap.put(field, val == null ? "null" : val.toString());
            }
            concatenatedValues = ObjectHashGenerator.generateHash(fieldMap);

        }

        String base64 = Base64.getEncoder().encodeToString(concatenatedValues.getBytes(StandardCharsets.UTF_8));

        String newHmac;
        try {
            newHmac = hmacClient.calculateHmac(base64);
//            newHmac = base64;
        } catch (Exception e) {
            log.error("调用 HMAC 服务失败", e);
            return R.fail("调用 HMAC 服务失败");
        }

        String originHmac = null;
        try {
            if (bizObj instanceof Map) {
                // 从 Map 中尝试拿“主业务对象”的 hmac
                Object mainObj = ((Map<?, ?>) bizObj).get("expert");

                if (mainObj != null) {
                    originHmac = (String) mainObj.getClass().getMethod("getHmac").invoke(mainObj);
                }
            } else {
                // bizObj 是单个实体，直接反射取getHmac()
                originHmac = (String) bizObj.getClass().getMethod("getHmac").invoke(bizObj);
            }
        } catch (Exception e) {
            log.warn("获取对象中hmac字段失败", e);
        }


        if (originHmac == null || originHmac.isEmpty()) {
            return R.fail("原始HMAC为空，无法校验完整性");
        }

        boolean match = Objects.equals(originHmac, newHmac);

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("match", match);
        resultMap.put("expected", originHmac);
        resultMap.put("actual", newHmac);

        return R.ok(resultMap);
    }


}
