package org.jeecg.ctop.material.service.support;

import com.alibaba.fastjson.JSONObject;
import org.jeecg.ctop.material.entity.vo.KuaiShouOperateGroupVo;
import org.jeecg.ctop.material.mapper.MaterialStareMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class DashboardQuerySupport {

    private static final long MANAGER_CACHE_TTL = 10 * 60 * 1000L;
    private static final long OPERATOR_CACHE_TTL = 10 * 60 * 1000L;
    private static final long TEAM_MEMBER_CACHE_TTL = 10 * 60 * 1000L;

    @Resource
    private MaterialStareMapper materialStareMapper;

    @Resource
    private DashboardLocalCacheService dashboardLocalCacheService;

    public List<KuaiShouOperateGroupVo> getOperationManagers(String roleCode) {
        return dashboardLocalCacheService.get("dashboard:managers:" + roleCode, MANAGER_CACHE_TTL, () -> new ArrayList<>(materialStareMapper.getOperationManagerUser(roleCode)));
    }

    public List<KuaiShouOperateGroupVo> getTencentOperationManagers() {
        return dashboardLocalCacheService.get("dashboard:managers:tencent", MANAGER_CACHE_TTL, () -> {
            List<KuaiShouOperateGroupVo> bytedanceManagers = getOperationManagers("touTiaoOperationManager");
            List<KuaiShouOperateGroupVo> kuaishouManagers = getOperationManagers("kuaishouOperationManager");
            Map<String, KuaiShouOperateGroupVo> managerMap = new LinkedHashMap<>();
            mergeManagers(managerMap, bytedanceManagers);
            mergeManagers(managerMap, kuaishouManagers);
            return new ArrayList<>(managerMap.values());
        });
    }

    public List<String> getAllOperationUserIds(String mediaId) {
        return dashboardLocalCacheService.get("dashboard:operators:" + mediaId, OPERATOR_CACHE_TTL, () -> new ArrayList<>(materialStareMapper.getAllOperationByMediaId(mediaId)));
    }

    public Map<String, Set<String>> getOperateTeamMembers(String mediaId, List<String> managerIds, Long startDate, Long endDate) {
        if (managerIds == null || managerIds.isEmpty()) {
            return Collections.emptyMap();
        }
        String managerKey = managerIds.stream().sorted().collect(Collectors.joining(","));
        String cacheKey = "dashboard:team:" + mediaId + ":" + managerKey + ":" + startDate + ":" + endDate;
        List<JSONObject> rows = dashboardLocalCacheService.get(cacheKey, TEAM_MEMBER_CACHE_TTL, () -> loadOperateTeamMembers(mediaId, managerIds, startDate, endDate));
        Map<String, Set<String>> result = new HashMap<>();
        if (rows == null) {
            return result;
        }
        for (JSONObject row : rows) {
            String managerId = row.getString("managerId");
            String userId = row.getString("userId");
            if (managerId == null || userId == null) {
                continue;
            }
            result.computeIfAbsent(managerId, key -> new LinkedHashSet<>()).add(userId);
        }
        return result;
    }

    private List<JSONObject> loadOperateTeamMembers(String mediaId, List<String> managerIds, Long startDate, Long endDate) {
        if ("1".equals(mediaId)) {
            return materialStareMapper.queryToutiaoOperateTeamMemberBatch(managerIds, startDate, endDate);
        }
        if ("16".equals(mediaId)) {
            return materialStareMapper.queryAdqOperateTeamMemberBatch(managerIds, startDate, endDate);
        }
        return materialStareMapper.queryKuaishouOperateTeamMemberBatch(managerIds, startDate, endDate);
    }

    private void mergeManagers(Map<String, KuaiShouOperateGroupVo> managerMap, List<KuaiShouOperateGroupVo> managers) {
        if (managers == null || managers.isEmpty()) {
            return;
        }
        for (KuaiShouOperateGroupVo manager : managers) {
            if (manager == null || manager.getUserId() == null) {
                continue;
            }
            managerMap.putIfAbsent(manager.getUserId(), manager);
        }
    }
}
