package com.qmth.sop.business.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qmth.sop.business.bean.dto.DataPermissionDto;
import com.qmth.sop.business.bean.result.TBQualityProblemApplyResult;
import com.qmth.sop.business.entity.SysUser;
import com.qmth.sop.business.entity.TBQualityProblemApply;
import com.qmth.sop.business.entity.TBService;
import com.qmth.sop.business.mapper.QualityAnalyseMapper;
import com.qmth.sop.business.service.QualityAnalyseService;
import com.qmth.sop.business.service.SysUserService;
import com.qmth.sop.common.enums.InfluenceDegreeEnum;
import com.qmth.sop.common.enums.QualityAnalyseGroupEnum;
import com.qmth.sop.common.enums.QualityProblemReasonEnum;
import com.qmth.sop.common.util.ServletUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class QualityAnalyseServiceImpl extends ServiceImpl<QualityAnalyseMapper, TBQualityProblemApply> implements QualityAnalyseService {

    @Resource
    private SysUserService sysUserService;

    @Override
    public List<TBService> list(Long startTime, Long endTime) {
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        DataPermissionDto dpr = sysUserService.buildUserDataPermission(requestUser.getId());
        return this.baseMapper.list(startTime, endTime, dpr);
    }


    @Override
    public Double progress(Long serviceUnitId) {
        return this.baseMapper.progress(serviceUnitId);
    }

    @Override
    public JSONObject influence(Long serviceUnitId, QualityAnalyseGroupEnum group) {
        List<Map<String, Object>> influence = this.baseMapper.influence(serviceUnitId);
//        Map<String, Map<String, Object>> result = new HashMap<>();
        JSONObject result = new JSONObject();

        if (group.equals(QualityAnalyseGroupEnum.INFLUENCE_REGION)) {
            influence.stream().filter(map -> map.get("region_name") != null).collect(Collectors.groupingBy(map -> map.get("region_name"))).forEach((k, v) -> {
//                Map<String, Object> map = new HashMap<>();
                JSONObject map = new JSONObject();
                v.stream().filter(map1 -> map1.get("Influence_degree") != null).collect(Collectors.groupingBy(map1 -> map1.get("Influence_degree"))).forEach((k1, v1) -> {
                    map.put(k1.toString(), v1.size());
                });
                map.put("id", v.get(0).get("region_id").toString());
                result.put(k.toString(), map);
            });
        } else if (group.equals(QualityAnalyseGroupEnum.INFLUENCE_SUPPLIER)) {
            influence.stream().filter(map -> map.get("Influence_degree") != null).collect(Collectors.groupingBy(map -> map.get("Influence_degree"))).forEach((k, v) -> {
                JSONObject map = new JSONObject();

                v.stream().filter(map1 -> map1.get("supplier") != null).collect(Collectors.groupingBy(map1 -> map1.get("supplier"))).forEach((k1, v1) -> {
                    JSONObject map1 = new JSONObject();
                    map1.put("value", v1.size());
                    map1.put("id", v.get(0).get("supplier_id").toString());
                    map.put(k1.toString(), map1);
                });
                result.put(k.toString(), map);
            });
        } else if (group.equals(QualityAnalyseGroupEnum.REASON_REGION)) {
            influence.stream().filter(map -> map.get("region_name") != null).collect(Collectors.groupingBy(map -> map.get("region_name"))).forEach((k, v) -> {
//                Map<String, Object> map = new HashMap<>();
                JSONObject map = new JSONObject();
                v.stream().filter(map1 -> map1.get("Influence_degree") != null).collect(Collectors.groupingBy(map1 -> map1.get("Influence_degree"))).forEach((k1, v1) -> {
                    map.put(k1.toString(), v1.size());
                });
                map.put("id", v.get(0).get("region_id").toString());
                result.put(k.toString(), map);
            });
        } else if (group.equals(QualityAnalyseGroupEnum.REASON_SUPPLIER)) {
            influence.stream().filter(map -> map.get("reason") != null).collect(Collectors.groupingBy(map -> map.get("reason"))).forEach((k, v) -> {
                JSONObject map = new JSONObject();

                v.stream().filter(map1 -> map1.get("supplier") != null).collect(Collectors.groupingBy(map1 -> map1.get("supplier"))).forEach((k1, v1) -> {
                    JSONObject map1 = new JSONObject();
                    map1.put("value", v1.size());
                    map1.put("id", v.get(0).get("supplier_id").toString());
                    map.put(k1.toString(), map1);
                });
                result.put(k.toString(), map);
            });
        }
        return result;
    }


    @Override
    public Map<String, Object> pie(Long serviceUnitId) {
        List<Map<String, Object>> pie = this.baseMapper.pie(serviceUnitId, null);
        Map<String, Object> result = new HashMap<>();
        pie.stream().filter(map1 -> map1.get("Influence_degree") != null).collect(Collectors.groupingBy(map -> map.get("Influence_degree"))).forEach((k, v) -> result.put(k.toString(), v.stream().filter(map1 -> map1.get("count") != null).mapToLong(map1 -> (long) map1.get("count")).sum()));
        return result;
    }

    @Override
    public Map<String, Map<String, Object>> radar(Long serviceUnitId, QualityAnalyseGroupEnum group) {
        List<Map<String, Object>> radar = this.baseMapper.radar(serviceUnitId, null);
        Map<String, Map<String, Object>> result = new HashMap<>();
        radar.stream().filter(map1 -> map1.get("reason") != null).collect(Collectors.groupingBy(map -> map.get("reason"))).forEach((k, v) -> {
            Map<String, Object> countMap = new HashMap<>(), map = new HashMap<>();
            countMap.put(k.toString(), v.stream().filter(map1 -> map1.get("count") != null).mapToLong(map1 -> (long) map1.get("count")).sum());
            if (result.containsKey("all")) {
                map = result.get("all");
                map.put(k.toString(), countMap.get(k.toString()));
            } else {
                map.put(k.toString(), countMap.get(k.toString()));
            }
            result.put("all", map);
        });

        if (group.equals(QualityAnalyseGroupEnum.REASON_REGION)) {
            radar.stream().filter(map1 -> map1.get("region_name") != null).collect(Collectors.groupingBy(map -> map.get("region_name"))).forEach((k, v) -> {
                Map<String, Object> z = new HashMap<>();
                v.stream().filter(map1 -> map1.get("reason") != null).collect(Collectors.groupingBy(map2 -> map2.get("reason"))).forEach((k1, v1) -> z.put(k1.toString(), v1.stream().filter(map1 -> map1.get("count") != null).mapToLong(map1 -> (long) map1.get("count")).sum()));
                result.put(k.toString(), z);
            });
        } else if (group.equals(QualityAnalyseGroupEnum.REASON_SUPPLIER)) {
            radar.stream().filter(map1 -> map1.get("supplier") != null).collect(Collectors.groupingBy(map -> map.get("supplier"))).forEach((k, v) -> {
                Map<String, Object> z = new HashMap<>();
                v.stream().filter(map1 -> map1.get("reason") != null).collect(Collectors.groupingBy(map2 -> map2.get("reason"))).forEach((k1, v1) -> z.put(k1.toString(), v1.stream().filter(map1 -> map1.get("count") != null).mapToLong(map1 -> (long) map1.get("count")).sum()));
                result.put(k.toString(), z);
            });
        }
        return result;
    }

    @Override
    public IPage<TBQualityProblemApplyResult> detail(Page<Object> objectPage, Long serviceUnitId, InfluenceDegreeEnum degree) {
        return this.baseMapper.detail(objectPage, serviceUnitId, Objects.nonNull(degree) ? degree.toString() : null);
    }

    @Override
    public IPage<TBQualityProblemApplyResult> influence(Page<Object> tPage, Long serviceUnitId, Long supplierId, Long region_id, InfluenceDegreeEnum influenceDegree, QualityProblemReasonEnum reason) {
        return this.baseMapper.influenceDetail(tPage, serviceUnitId, supplierId, region_id, Objects.nonNull(influenceDegree) ? influenceDegree.toString() : null, Objects.nonNull(reason) ? reason.toString() : null);
    }
}
