package com.yeejoin.amos.boot.module.cylinder.flc.biz.service.impl;

import cn.hutool.core.date.DateUtil;
import com.yeejoin.amos.boot.module.common.api.dto.DPFilterParamDto;
import com.yeejoin.amos.boot.module.cylinder.api.dto.EquipQuestionNumCountDto;
import com.yeejoin.amos.boot.module.cylinder.api.enums.EquipmentClassifityEnum;
import com.yeejoin.amos.boot.module.cylinder.api.mapper.DPStatisticsMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@Service
public class DPStatisticsServiceImpl {

    private static Map<String, String> regionCodeOrgCodeMap = new ConcurrentHashMap<>();

    private DPStatisticsMapper statisticsMapper;

    public DPStatisticsServiceImpl(DPStatisticsMapper statisticsMapper) {
        this.statisticsMapper = statisticsMapper;
    }

    public List<Map<String, Object>> getEquipQuestionList(DPFilterParamDto dpFilterParamDto) {
        this.setDefaultFilter(dpFilterParamDto);
        String orgCode = this.getAndSetOrgCode(dpFilterParamDto.getCityCode());
        if(StringUtils.isEmpty(orgCode)){
            return new ArrayList<>();
        }
        List<EquipQuestionNumCountDto> equipQuestionNumCountDtos = statisticsMapper.queryEquipQuestionList(orgCode, dpFilterParamDto);
        return this.calPercentFinishedAndCast2Map(equipQuestionNumCountDtos);
    }

    private List<Map<String, Object>> calPercentFinishedAndCast2Map(List<EquipQuestionNumCountDto> equipQuestionNumCountDtos) {
        return equipQuestionNumCountDtos.stream().map(e -> {
            Map<String, Object> item = new HashMap<>();
            // 设备id
            item.put("key", e.getSourceId());
            // 区域名称
            item.put("regionName", e.getCityName());
            // 设备种类
            item.put("deviceCategoryName", EquipmentClassifityEnum.getNameByCode(e.getEquList()));
            // 监管码/使用登记证编号
            item.put("code", this.buildCodeWithSplit(e.getSupervisoryCode(), e.getUseOrgCode()));
            // 使用单位
            item.put("useUnitName", e.getUseUnitName());
            // 问题次数
            item.put("issuesNumber", e.getTotal());
            // 闭环率
            item.put("closedLoopRate", this.calClosedLoopRate(e.getTotal(), e.getFinished()));
            return item;
        }).collect(Collectors.toList());
    }

    private String calClosedLoopRate(Long total, Long finished) {
        if (total == 0) {
            return "0";
        }
        BigDecimal totalBig = new BigDecimal(total.toString());
        BigDecimal finishedBig = new BigDecimal(finished.toString());
        BigDecimal result = finishedBig.divide(totalBig, 2, RoundingMode.HALF_UP);
        NumberFormat nt = NumberFormat.getPercentInstance();
        nt.setMinimumFractionDigits(0);
        return nt.format(result);
    }

    private String buildCodeWithSplit(String supervisoryCode, String useOrgCode) {
        if (StringUtils.isNotEmpty(supervisoryCode) && StringUtils.isNotEmpty(useOrgCode)) {
            return String.format("%s/%s", supervisoryCode, useOrgCode);
        }
        if (StringUtils.isNotEmpty(supervisoryCode)) {
            return supervisoryCode;
        }
        if (StringUtils.isNotEmpty(useOrgCode)) {
            return useOrgCode;
        }
        return "";
    }

    private void setDefaultFilter(DPFilterParamDto dpFilterParamDto) {
        if (StringUtils.isEmpty(dpFilterParamDto.getBeginDate())) {
            dpFilterParamDto.setBeginDate(DateUtil.lastMonth().toDateStr());
        }
        if (StringUtils.isEmpty(dpFilterParamDto.getEndDate())) {
            dpFilterParamDto.setEndDate(DateUtil.today());
        }
    }


    private String getAndSetOrgCode(String region) {
        String orgCode = regionCodeOrgCodeMap.get(region);
        if (orgCode == null) {
            orgCode = statisticsMapper.getOrgCodeByCompanyCode(region);
            if (orgCode != null) {
                regionCodeOrgCodeMap.put(region, orgCode);
            }
        }
        return orgCode;
    }
}
