package com.ruoyi.excel.wecom.service;

import com.ruoyi.excel.wecom.domain.CustomerDataChangeLog;
import com.ruoyi.excel.wecom.domain.CustomerExportData;
import com.ruoyi.excel.wecom.domain.CustomerExportDataHistory;
import com.ruoyi.excel.wecom.mapper.CustomerDataChangeLogMapper;
import com.ruoyi.excel.wecom.mapper.CustomerExportDataHistoryMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.security.MessageDigest;
import java.util.*;

/**
 * 客户数据变更追踪服务
 * 提供数据指纹计算、变更检测、历史记录保存等功能
 */
@Service
public class CustomerDataChangeTrackingService {

    @Autowired
    private CustomerExportDataHistoryMapper historyMapper;

    @Autowired
    private CustomerDataChangeLogMapper changeLogMapper;

    /**
     * 字段中文名称映射
     */
    private static final Map<String, String> FIELD_LABEL_MAP = new HashMap<>();

    static {
        FIELD_LABEL_MAP.put("customerName", "客户名称");
        FIELD_LABEL_MAP.put("description", "描述");
        FIELD_LABEL_MAP.put("gender", "性别");
        FIELD_LABEL_MAP.put("addUserName", "添加人");
        FIELD_LABEL_MAP.put("addUserAccount", "添加人账号");
        FIELD_LABEL_MAP.put("addUserDepartment", "添加人所属部门");
        FIELD_LABEL_MAP.put("addTime", "添加时间");
        FIELD_LABEL_MAP.put("addDate", "添加日期");
        FIELD_LABEL_MAP.put("source", "来源");
        FIELD_LABEL_MAP.put("mobile", "手机");
        FIELD_LABEL_MAP.put("company", "企业");
        FIELD_LABEL_MAP.put("email", "邮箱");
        FIELD_LABEL_MAP.put("address", "地址");
        FIELD_LABEL_MAP.put("position", "职务");
        FIELD_LABEL_MAP.put("phone", "电话");
        FIELD_LABEL_MAP.put("tagGroup1", "标签组1(投放)");
        FIELD_LABEL_MAP.put("tagGroup2", "标签组2(公司孵化)");
        FIELD_LABEL_MAP.put("tagGroup3", "标签组3(商务)");
        FIELD_LABEL_MAP.put("tagGroup4", "标签组4(成交日期)");
        FIELD_LABEL_MAP.put("tagGroup5", "标签组5(年级组)");
        FIELD_LABEL_MAP.put("tagGroup6", "标签组6(客户属性)");
        FIELD_LABEL_MAP.put("tagGroup7", "标签组7(成交)");
        FIELD_LABEL_MAP.put("tagGroup8", "标签组8(成交品牌)");
        FIELD_LABEL_MAP.put("tagGroup9", "标签组9(线索通标签)");
        FIELD_LABEL_MAP.put("tagGroup10", "标签组10(A1组)");
        FIELD_LABEL_MAP.put("tagGroup11", "标签组11(B1组)");
        FIELD_LABEL_MAP.put("tagGroup12", "标签组12(C1组)");
        FIELD_LABEL_MAP.put("tagGroup13", "标签组13(D1组)");
        FIELD_LABEL_MAP.put("tagGroup14", "标签组14(E1组)");
        FIELD_LABEL_MAP.put("tagGroup15", "标签组15(意向度)");
        FIELD_LABEL_MAP.put("tagGroup16", "标签组16(自然流)");
        FIELD_LABEL_MAP.put("tagGroup17", "标签组17(F1组)");
        FIELD_LABEL_MAP.put("tagGroup18", "标签组18(G1组)");
    }

    /**
     * 计算数据指纹（MD5哈希值）
     * 基于所有业务字段生成唯一标识，用于快速判断数据是否变更
     *
     * @param data 客户导出数据
     * @return MD5哈希值
     */
    public String calculateDataFingerprint(CustomerExportData data) {
        if (data == null) {
            return null;
        }

        try {
            // 构建用于计算指纹的字符串（排除id字段）
            StringBuilder sb = new StringBuilder();
            sb.append(data.getCustomerUserId()).append("|");
            sb.append(data.getCustomerName()).append("|");
            sb.append(data.getDescription()).append("|");
            sb.append(data.getGender()).append("|");
            sb.append(data.getAddUserName()).append("|");
            sb.append(data.getAddUserAccount()).append("|");
            sb.append(data.getAddUserDepartment()).append("|");
            sb.append(data.getAddTime()).append("|");
            sb.append(data.getAddDate()).append("|");
            sb.append(data.getSource()).append("|");
            sb.append(data.getMobile()).append("|");
            sb.append(data.getCompany()).append("|");
            sb.append(data.getEmail()).append("|");
            sb.append(data.getAddress()).append("|");
            sb.append(data.getPosition()).append("|");
            sb.append(data.getPhone()).append("|");
            sb.append(data.getTagGroup1()).append("|");
            sb.append(data.getTagGroup2()).append("|");
            sb.append(data.getTagGroup3()).append("|");
            sb.append(data.getTagGroup4()).append("|");
            sb.append(data.getTagGroup5()).append("|");
            sb.append(data.getTagGroup6()).append("|");
            sb.append(data.getTagGroup7()).append("|");
            sb.append(data.getTagGroup8()).append("|");
            sb.append(data.getTagGroup9()).append("|");
            sb.append(data.getTagGroup10()).append("|");
            sb.append(data.getTagGroup11()).append("|");
            sb.append(data.getTagGroup12()).append("|");
            sb.append(data.getTagGroup13()).append("|");
            sb.append(data.getTagGroup14()).append("|");
            sb.append(data.getTagGroup15()).append("|");
            sb.append(data.getTagGroup16()).append("|");
            sb.append(data.getTagGroup17()).append("|");
            sb.append(data.getFinishDate()).append("|");
            sb.append(data.getTagGroup18());

            // 计算MD5
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(sb.toString().getBytes("UTF-8"));

            // 转换为16进制字符串
            StringBuilder hexString = new StringBuilder();
            for (byte b : digest) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (Exception e) {
            throw new RuntimeException("计算数据指纹失败", e);
        }
    }

    /**
     * 检查数据是否发生变更
     *
     * @param customerId 客户ID
     * @param newData 新数据
     * @return true-数据已变更，false-数据未变更
     */
    public boolean hasDataChanged(Long customerId, CustomerExportData newData) {
        if (customerId == null || newData == null) {
            return true;
        }

        // 计算新数据的指纹
        String newFingerprint = calculateDataFingerprint(newData);

        // 查询最新的历史记录
        Integer maxVersion = historyMapper.selectMaxVersionByCustomerId(customerId);
        if (maxVersion == null || maxVersion == 0) {
            // 没有历史记录，说明是新数据
            return true;
        }

        // 查询最新版本的历史记录
        CustomerExportDataHistory latestHistory = historyMapper.selectByCustomerIdAndVersion(customerId, maxVersion);
        if (latestHistory == null) {
            return true;
        }

        // 比较指纹
        return !newFingerprint.equals(latestHistory.getDataFingerprint());
    }

    /**
     * 保存数据变更记录（包括历史快照和变更日志）
     *
     * @param customerId 客户ID
     * @param newData 新数据
     * @param changeType 变更类型：INSERT-新增, UPDATE-更新, DELETE-删除
     * @return 历史记录ID
     */
    @Transactional(rollbackFor = Exception.class)
    public Long saveDataChange(String cropId,Long customerId, CustomerExportData newData, String changeType) {
        if (customerId == null || newData == null) {
            return null;
        }

        // 1. 获取当前最新版本号
        Integer maxVersion = historyMapper.selectMaxVersionByCustomerId(customerId);
        int newVersion = (maxVersion == null ? 0 : maxVersion) + 1;

        // 2. 计算数据指纹
        String dataFingerprint = calculateDataFingerprint(newData);

        // 3. 创建历史记录
        CustomerExportDataHistory history = new CustomerExportDataHistory();
        BeanUtils.copyProperties(newData, history);
        history.setCorpId(cropId);
        history.setHistoryId(null); // 清除ID，让数据库自动生成
        history.setCustomerId(customerId);
        history.setVersion(newVersion);
        history.setDataFingerprint(dataFingerprint);
        history.setChangeType(changeType);
        history.setChangeTime(new Date());

        // 4. 保存历史记录
        historyMapper.insert(history);

        // 5. 如果是更新操作，记录具体的字段变更
        if ("UPDATE".equals(changeType) && newVersion > 1) {
            // 获取上一个版本的数据
            CustomerExportDataHistory previousHistory = historyMapper.selectByCustomerIdAndVersion(customerId, newVersion - 1);
            if (previousHistory != null) {
                // 比较字段变更
                List<CustomerDataChangeLog> changeLogs = compareAndGenerateChangeLogs(cropId,
                        history.getHistoryId(), customerId, newVersion, previousHistory, history);

                // 批量保存变更日志
                if (!changeLogs.isEmpty()) {
                    changeLogMapper.batchInsert(changeLogs);
                }
            }
        }

        return history.getHistoryId();
    }

    /**
     * 比较两个版本的数据，生成变更日志
     *
     * @param historyId 历史记录ID
     * @param customerId 客户ID
     * @param version 版本号
     * @param oldData 旧数据
     * @param newData 新数据
     * @return 变更日志列表
     */
    private List<CustomerDataChangeLog> compareAndGenerateChangeLogs(String corpId,
            Long historyId, Long customerId, Integer version,
            CustomerExportDataHistory oldData, CustomerExportDataHistory newData) {

        List<CustomerDataChangeLog> changeLogs = new ArrayList<>();
        Date changeTime = new Date();

        try {
            // 获取所有字段
            Field[] fields = CustomerExportDataHistory.class.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                String fieldName = field.getName();

                // 跳过不需要比较的字段
                if (shouldSkipField(fieldName)) {
                    continue;
                }

                // 获取旧值和新值
                Object oldValue = field.get(oldData);
                Object newValue = field.get(newData);

                // 比较值是否变更
                if (!Objects.equals(oldValue, newValue)) {
                    CustomerDataChangeLog changeLog = new CustomerDataChangeLog();
                    changeLog.setHistoryId(historyId);
                    changeLog.setCustomerId(customerId);
                    changeLog.setFieldName(fieldName);
                    changeLog.setFieldLabel(FIELD_LABEL_MAP.getOrDefault(fieldName, fieldName));
                    changeLog.setOldValue(oldValue != null ? oldValue.toString() : null);
                    changeLog.setNewValue(newValue != null ? newValue.toString() : null);
                    changeLog.setChangeTime(changeTime);
                    changeLog.setVersion(version);
                    changeLog.setCorpId(corpId);

                    changeLogs.add(changeLog);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("比较数据变更失败", e);
        }

        return changeLogs;
    }

    /**
     * 判断字段是否需要跳过比较
     */
    private boolean shouldSkipField(String fieldName) {
        return "serialVersionUID".equals(fieldName)
                || "historyId".equals(fieldName)
                || "customerId".equals(fieldName)
                || "version".equals(fieldName)
                || "dataFingerprint".equals(fieldName)
                || "changeType".equals(fieldName)
                || "changeTime".equals(fieldName);
    }

    /**
     * 查询客户的所有历史版本
     *
     * @param customerId 客户ID
     * @return 历史记录列表
     */
    public List<CustomerExportDataHistory> getCustomerHistory(Long customerId) {
        return historyMapper.selectHistoryByCustomerId(customerId);
    }

    /**
     * 查询客户的所有变更日志
     *
     * @param customerId 客户ID
     * @return 变更日志列表
     */
    public List<CustomerDataChangeLog> getCustomerChangeLogs(Long customerId) {
        return changeLogMapper.selectChangeLogByCustomerId(customerId);
    }

    /**
     * 查询指定版本的变更日志
     *
     * @param customerId 客户ID
     * @param version 版本号
     * @return 变更日志列表
     */
    public List<CustomerDataChangeLog> getChangeLogsByVersion(Long customerId, Integer version) {
        return changeLogMapper.selectChangeLogByCustomerIdAndVersion(customerId, version);
    }
}
