package com.yaoyicloud.render.cso;

import java.io.IOException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import com.yaoyicloud.easier.common.file.core.FileProperties;
import com.yaoyicloud.easier.common.file.core.FileTemplate;
import com.yaoyicloud.factory.CSOAbstractRender;

import org.apache.commons.collections4.MapUtils;

import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import com.deepoove.poi.policy.DynamicTableRenderPolicy;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.primitives.Longs;
import com.google.protobuf.ByteString;
import com.google.protobuf.ListValue;
import com.google.protobuf.util.JsonFormat;
import com.yaoyicloud.config.CommonDataCache;
import com.yaoyicloud.config.FilerepoProperties;
import com.yaoyicloud.message.CSOProtos;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public final class EntPromotionSummaryRender extends CSOAbstractRender {
    private final FilerepoProperties filerepoProperties;
    private final CommonDataCache commonDataCache;

    public EntPromotionSummaryRender(String cwd, FileTemplate ossTemplate, FileProperties properties,
        FilerepoProperties filerepoProperties,
        CommonDataCache commonDataCache) {
        super(cwd, ossTemplate, properties);
        this.filerepoProperties = filerepoProperties;
        this.commonDataCache = commonDataCache;
    }

    @Override
    protected Map<String, Object> renderDocx(String info, String relationId, Integer counter) throws IOException {
        log.info("开始渲染CSO企业报告推广总结模块，relationId: {}", relationId);

        CSOProtos.PromotionSummary.Builder promotionSummary = CSOProtos.PromotionSummary.newBuilder();
        JsonFormat.parser().merge(info, promotionSummary);

        // 获取用户提交的积分数据
        Map<String, ByteString> userSubmittedScoreMapMap = promotionSummary.getUserSubmittedScoreMapMap();

        // 关键步骤：将Protobuf的bytes数据转换为Map<String, List<Integer>>
        Map<String, List<Integer>> userScoreMap = new HashMap<>();
        for (Map.Entry<String, ByteString> entry : userSubmittedScoreMapMap.entrySet()) {
            String userId = entry.getKey();
            ByteString byteString = entry.getValue();
            // 解析bytes为ListValue
            ListValue listValue = ListValue.parseFrom(byteString);
            // 转换为List<Integer>
            List<Integer> scoreList = listValue.getValuesList().stream()
                .map(value -> (int) value.getNumberValue())
                .collect(Collectors.toList());
            userScoreMap.put(userId, scoreList);
        }
        CSOProtos.PromotionSummary defaultInstance = CSOProtos.PromotionSummary.getDefaultInstance();
        CSOProtos.PromotionSummary mergedProto = defaultInstance.toBuilder()
            .mergeFrom(promotionSummary.build())
            .build();

        String completeJson = JsonFormat.printer()
            .includingDefaultValueFields()
            .print(mergedProto);

        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> data = objectMapper.readValue(completeJson, new TypeReference<Map<String, Object>>() {});
        // 将用户积分数据添加到渲染数据中
        data.put("userScoreMap", userScoreMap); // 这将使数据在模板中可用
        Map<String, Object> commonDataCacheData = commonDataCache.getData(relationId);
        if (MapUtils.isNotEmpty(commonDataCacheData)) {
            data.putAll(commonDataCacheData);
        }
        data.put("levelInteger", counter);
        fillDefaultValues(data);
        commonDataCache.insertData(relationId, "userNameMap", data.get("userNameMap"));
        return data;
    }

    @Override
    protected ConfigureBuilder builder(String relationId) {
        ConfigureBuilder builder = Configure.builder();
        DynamicTableRenderPolicy twoLevelTableDynamicPolicy = getTwoLevelTableDynamicPolicy();
        DynamicTableRenderPolicy lastRowDaynamicPolicy = getTableLastRowDynamicPolicy();
        Map<String, Object> commonDataCacheData = commonDataCache.getData(relationId);

        DynamicTableRenderPolicy tableDynamicPolicy = super.getDynamicTableRenderPolicy(commonDataCacheData);
        builder.bind("task_analysis_5_1", twoLevelTableDynamicPolicy);
        builder.bind("task_promotion_count_5_1_1", twoLevelTableDynamicPolicy);
        builder.bind("task_promotion_count_5_1_1_last", lastRowDaynamicPolicy);
        builder.bind("task_promotioner_5_4", tableDynamicPolicy);
        builder.bind("task_promotioner_quality_5_4_1", this.indicatorsRenderPolicyToProtobuf());
        builder.bind("task_promotioner_quality_5_4_1_last", lastRowDaynamicPolicy);
        return builder;
    }

    @Override
    protected String getBasicPath() throws IOException {
        return filerepoProperties.getBasePath();
    }

    @Override
    protected String getReportImagePath() {
        return filerepoProperties.getReportImagePath();
    }

    /**
     * 填充默认值，确保所有必要字段都存在
     */
    @SuppressWarnings("checkstyle:MethodLength")
    private void fillDefaultValues(Map<String, Object> data) {

        Integer submitedTaskScore = (Integer) data.get("submitedTaskScore");
        Integer totalApprovedScore = (Integer) data.get("totalApprovedScore");
        data.put("rejectedTaskScore", submitedTaskScore - totalApprovedScore);
        // 提取任务类型元数据（taskTypeMetas）
        List<Map<String, Object>> taskTypeMetas = (List<Map<String, Object>>) data.get("taskTypeMetas");
        // 提取按类型统计的任务数据（taskStatsByType）
        List<Map<String, Object>> taskStatsByTypeList = (List<Map<String, Object>>) data.get("taskStatsByType");
        // 提取按用户统计的任务数据（taskStatsByPerson）
        List<Map<String, Object>> taskStatsByPersonList = (List<Map<String, Object>>) data.get("taskStatsByPerson");
        // 提取全局统计字段
        int approvedCnt = (Integer) data.getOrDefault("taskPromotionerQuality541ApprovedCnt", 0);
        int submittedCnt = (Integer) data.getOrDefault("taskPromotionerQuality541SubmittedCnt", 0);
        int rejectedCnt = (Integer) data.getOrDefault("taskPromotionerQuality541RejectedCnt", 0);

        Map<String, List<Integer>> userScoreMap = (Map<String, List<Integer>>) data.get("userScoreMap");
        Long scoreSum = 0L;
        for (Map.Entry<String, List<Integer>> stringListEntry : userScoreMap.entrySet()) {
            scoreSum += stringListEntry.getValue().stream().mapToLong(Long::valueOf).sum();
        }

        Map<String, String> userNameMap = taskTypeMetas.stream()
            .collect(Collectors.toMap(
                m -> m.get("userId").toString(),
                m -> m.get("userName").toString(),
                (oldValue, newValue) -> oldValue));

        data.put("userNameMap", userNameMap);
        // 2. 复现 task_analysis_5_1（按任务类型的统计分析）
        Map<String, List<List<Object>>> taskAnalysis51 = new HashMap<>();
        Map<String, Integer> mpParentTypeCount = new HashMap<>();
        Map<String, Long> mpParentTypeScore = new HashMap<>();

        // 解析taskStatsByType（protobuf中是列表，实际应为单个对象，取第一个）
        if (!taskStatsByTypeList.isEmpty()) {
            Map<String, Object> taskStatsByType = taskStatsByTypeList.get(0);
            Map<String, Map<String, Object>> taskStatsMap =
                (Map<String, Map<String, Object>>) taskStatsByType.get("taskStats");

            for (Map.Entry<String, Map<String, Object>> entry : taskStatsMap.entrySet()) {
                String taskTypeId = entry.getKey();
                Map<String, Object> taskStat = entry.getValue();
                int count = (Integer) taskStat.get("count");
                Object o = taskStat.get("score");
                Long score = Longs.tryParse(o.toString());

                // 从taskTypeMetas中获取父/子分类名称（根据taskTypeId匹配）
                String parentName = "";
                String childName = "";
                for (Map<String, Object> meta : taskTypeMetas) {
                    if (meta.get("taskTypeId").equals(taskTypeId)) {
                        parentName = (String) meta.get("parentName");
                        childName = (String) meta.get("childName");
                        break;
                    }
                }

                // 构建行数据
                List<Object> row = new ArrayList<>();
                row.add(childName);
                row.add(count);
                row.add(count * 1.0 / approvedCnt); // 占比=当前类型数量/总通过数量
                row.add(score);

                row.add(score * 1d / scoreSum); // 积分占比

                // 按父分类分组
                List<List<Object>> rowList = taskAnalysis51.getOrDefault(parentName, new ArrayList<>());
                rowList.add(row);
                taskAnalysis51.put(parentName, rowList);

                // 更新父分类的总数量和积分
                mpParentTypeCount.put(parentName, mpParentTypeCount.getOrDefault(parentName, 0) + count);
                mpParentTypeScore.put(parentName, mpParentTypeScore.getOrDefault(parentName, 0L) + score);
            }
        }
        data.put("task_analysis_5_1", taskAnalysis51);

        // 复现 task_analysis_5_1 的最大值（最多任务的父分类）
        if (!mpParentTypeCount.isEmpty()) {

            Map<String, Integer> starTaskMap = (Map<String, Integer>) data.get("starTaskMap");
            Map.Entry<String, Integer> maxEntry = starTaskMap.entrySet().iterator().next();
            data.put("task_analysis_5_1_maxName", maxEntry.getKey());
            data.put("task_analysis_5_1_maxCount", maxEntry.getValue().toString());
            // 计算最大父分类的积分占比
            long maxParentScore = mpParentTypeScore.getOrDefault(maxEntry.getKey(), 0L);
            data.put("task_analysis_5_1_maxPercent", String.format("%.2f", maxParentScore * 1.0 / scoreSum * 100));
        }

        // 3. 复现 task_promotion_count_5_1_1（按任务类型的推广人统计）
        Map<String, List<List<Object>>> taskPromotionCount511 = new HashMap<>();
        Set<String> allPromotioners = new HashSet<>(); // 所有推广人ID

        if (!taskStatsByTypeList.isEmpty()) {
            Map<String, Object> taskStatsByType = taskStatsByTypeList.get(0);
            Map<String, Map<String, Object>> taskStatsMap =
                (Map<String, Map<String, Object>>) taskStatsByType.get("taskStats");

            for (Map.Entry<String, Map<String, Object>> entry : taskStatsMap.entrySet()) {
                String taskTypeId = entry.getKey();
                Map<String, Object> taskStat = entry.getValue();
                int count = (Integer) taskStat.get("count");
                List<String> promotioners = (List<String>) taskStat.get("promotioners"); // 该任务类型的推广人列表
                if (promotioners != null) {
                    allPromotioners.addAll(promotioners);
                }

                // 从taskTypeMetas中获取父/子分类名称
                String parentName = "";
                String childName = "";
                for (Map<String, Object> meta : taskTypeMetas) {
                    if (meta.get("taskTypeId").equals(taskTypeId)) {
                        parentName = (String) meta.get("parentName");
                        childName = (String) meta.get("childName");
                        break;
                    }
                }

                // 构建行数据
                List<Object> row = new ArrayList<>();
                row.add(childName);
                row.add(promotioners != null ? promotioners.size() : 0); // 推广人数
                row.add(count); // 任务数量
                row.add(promotioners != null && !promotioners.isEmpty() ? count * 1.0 / promotioners.size() : 0); // 人均任务数

                // 按父分类分组
                List<List<Object>> rowList = taskPromotionCount511.getOrDefault(parentName, new ArrayList<>());
                rowList.add(row);
                taskPromotionCount511.put(parentName, rowList);
            }
        }
        data.put("task_promotion_count_5_1_1", taskPromotionCount511);

        // 复现推广人平均任务数
        int promotionerCount = allPromotioners.size();
        String avgByPerson =
            promotionerCount > 0 ? String.format("%.2f", approvedCnt * 1.0 / promotionerCount) : "0.00";
        data.put("task_promotion_count_5_1_1_avg", avgByPerson);

        // 复现task_promotion_count_5_1_1_last（合计行）
        List<Object> lastRow511 = new ArrayList<>();
        lastRow511.add(null); // label
        lastRow511.add(promotionerCount); // 总推广人数
        lastRow511.add(approvedCnt); // 总任务数
        lastRow511.add(avgByPerson); // 平均任务数
        data.put("task_promotion_count_5_1_1_last", lastRow511);

        // 4. 复现 task_promotioner_5_4（按推广人的任务类型统计）
        Map<String, List<List<Object>>> taskPromotioner54 = new HashMap<>();

        if (!taskStatsByPersonList.isEmpty()) {
            Map<String, Object> taskStatsByPerson = taskStatsByPersonList.get(0);
            Map<String, Map<String, Object>> userStatsMap =
                (Map<String, Map<String, Object>>) taskStatsByPerson.get("userStats");

            for (Map.Entry<String, Map<String, Object>> userEntry : userStatsMap.entrySet()) {
                String userId = userEntry.getKey();
                Map<String, Object> userTaskStats = userEntry.getValue();
                Map<String, Map<String, Object>> taskStatsByUser =
                    (Map<String, Map<String, Object>>) userTaskStats.get("taskStats");

                // 获取用户名（从taskTypeMetas中匹配）
                // String userName = "无姓名";
                // for (Map<String, Object> meta : taskTypeMetas) {
                // if (meta.get("userId").equals(userId)) {
                // userName = (String) meta.get("userName");
                // break;
                // }
                // }

                // 构建该用户的任务统计行
                List<List<Object>> rowList = new ArrayList<>();
                for (Map.Entry<String, Map<String, Object>> taskEntry : taskStatsByUser.entrySet()) {
                    String taskTypeId = taskEntry.getKey();
                    Map<String, Object> taskStat = taskEntry.getValue();
                    int count = (Integer) taskStat.get("count");
                    Object o = taskStat.get("score");
                    Long score = Longs.tryParse(o.toString());
                    // 获取任务类型名称
                    String taskTypeName = "";
                    for (Map<String, Object> meta : taskTypeMetas) {
                        if (meta.get("taskTypeId").equals(taskTypeId)) {
                            taskTypeName = (String) meta.get("childName");
                            break;
                        }
                    }

                    List<Object> row = new ArrayList<>();
                    row.add(taskTypeName);
                    row.add(count);
                    row.add(count * 1.0 / approvedCnt); // 任务占比
                    row.add(score);
                    row.add(score * 1d / scoreSum);
                    rowList.add(row);
                }
                taskPromotioner54.put(userId, rowList);
            }
        }
        data.put("task_promotioner_5_4", taskPromotioner54);

        // 5. 复现 task_promotioner_quality_5_4_1（推广人质量统计）
        List<Map<String, Object>> taskPromotionerQuality541 = new ArrayList<>();
        int idx = 1;

        if (!taskStatsByPersonList.isEmpty()) {
            Map<String, Object> taskStatsByPerson = taskStatsByPersonList.get(0);
            Map<String, Map<String, Object>> userStatsMap =
                (Map<String, Map<String, Object>>) taskStatsByPerson.get("userStats");

            for (Map.Entry<String, Map<String, Object>> userEntry : userStatsMap.entrySet()) {
                String userId = userEntry.getKey();
                Map<String, Object> userTaskStats = userEntry.getValue();
                Map<String, Map<String, Object>> taskStatsByUser =
                    (Map<String, Map<String, Object>>) userTaskStats.get("taskStats");

                // 计算该用户的总通过任务数和积分
                int userApprovedCnt = 0;
                long userApprovedScore = 0L;
                for (Map<String, Object> taskStat : taskStatsByUser.values()) {
                    userApprovedCnt += (Integer) taskStat.get("count");
                    userApprovedScore += Longs.tryParse(taskStat.get("score").toString());

                }

                int userSubmittedCnt = 0;
                int userSubmittedScore = 0;
                // 获取用户名
                String userName = "无姓名";
                for (Map<String, Object> meta : taskTypeMetas) {
                    if (meta.get("userId").equals(userId)) {
                        userSubmittedCnt = userScoreMap.get(meta.get("userId").toString()).size();
                        userSubmittedScore =
                            userScoreMap.get(meta.get("userId")).stream().mapToInt(Integer::intValue).sum();
                        userName = (String) meta.get("userName");
                        break;
                    }
                }

                // 构建行数据
                Map<String, Object> row = new HashMap<>();
                row.put("seq", idx++);
                row.put("promotioner", userName);
                row.put("submittedCnt", userSubmittedCnt);
                row.put("approvedCnt", userApprovedCnt);
                row.put("taskRate", userSubmittedCnt > 0
                    ? String.format("%.2f%%", userApprovedCnt * 1.0 / userSubmittedCnt * 100) : "0.00%");
                row.put("submittedScore", userSubmittedScore);
                row.put("approvedScore", userApprovedScore);
                row.put("scoreRate", userSubmittedScore > 0
                    ? String.format("%.2f%%", userApprovedScore * 1.0 / userSubmittedScore * 100) : "0.00%");
                taskPromotionerQuality541.add(row);
            }
        }

        data.put("task_promotioner_quality_5_4_1", taskPromotionerQuality541);

        // 6. 复现 task_promotioner_quality_5_4_1_last（合计行）
        List<Object> lastRow541 = new ArrayList<>();
        lastRow541.add(null); // label
        lastRow541.add(submittedCnt); // 总提交数
        lastRow541.add(approvedCnt); // 总通过数
        String taskRate = submittedCnt > 0 ? String.format("%.2f%%", approvedCnt * 1.0 / submittedCnt * 100) : "0.00%";
        lastRow541.add(taskRate);
        Long totalSubmittedScore = Longs.tryParse(scoreSum.toString());
        lastRow541.add(totalSubmittedScore);
        lastRow541.add(scoreSum); // 总通过积分
        String scoreRate =
            totalSubmittedScore > 0 ? String.format("%.2f%%", scoreSum * 1.0 / totalSubmittedScore * 100) : "0.00%";
        lastRow541.add(scoreRate);
        data.put("task_promotioner_quality_5_4_1_last", lastRow541);

        // 7. 填充其他字段
        data.put("task_promotioner_quality_5_4_1_taskRate", taskRate.replace("%", ""));
        data.put("task_promotioner_quality_5_4_1_scoreRate", scoreRate.replace("%", ""));
        data.put("task_promotioner_quality_5_4_1_approvedCnt", approvedCnt);
        data.put("task_promotioner_quality_5_4_1_submittedCnt", submittedCnt);
        data.put("task_promotioner_quality_5_4_1_rejectedCnt", rejectedCnt);
    }

}
