package com.nokia.hb.service;

import com.nokia.common.R;
import com.nokia.common.exception.BizException;
import com.nokia.hb.dao.entity.PerCfgIndicator;
import com.nokia.hb.dao.mapper.PerCfgCellMapper;
import com.nokia.hb.dao.mapper.PerCfgIndicatorMapper;
import com.nokia.hb.pojo.Col;
import com.nokia.hb.pojo.RetData;
import com.nokia.hb.pojo.dto.RenderTableDto;
import com.nokia.hb.pojo.enums.NetTypeEnum;
import com.nokia.hb.pojo.enums.SearchTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpSession;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
@Service
public class PmService {
    private final PerCfgIndicatorMapper perCfgIndicatorMapper;
    private final PerCfgCellMapper perCfgCellMapper;

    public PmService(PerCfgIndicatorMapper perCfgIndicatorMapper, PerCfgCellMapper perCfgCellMapper) {
        this.perCfgIndicatorMapper = perCfgIndicatorMapper;
        this.perCfgCellMapper = perCfgCellMapper;
    }

    public R<RetData> renderTable(RenderTableDto dto, HttpSession session) {
        List<Map<String, Object>> list = new ArrayList<>();
        Set<String> indicatorSet = perCfgIndicatorMapper.listByIds(dto.getIndicators());
        indicatorSet.add("eci");
        indicatorSet.add("sdate");
        String indicators = String.join(",", indicatorSet);
        List<Col> cols = getCols(indicatorSet);
        // 按地市查询
        if (SearchTypeEnum.AREA.equals(dto.getSearchType())) {
            checkAreaPermission(dto, session);
            if (!CollectionUtils.isEmpty(dto.getLteQuxians())) {
                List<Map<String, Object>> l = perCfgCellMapper.searchByCity(NetTypeEnum.LTE.name(), dto.getLteCitys(),
                        dto.getLteQuxians(), indicators, dto.getTimeType().name().toLowerCase(), dto.getStartTime(),
                        dto.getEndTime());
                list.addAll(l);
            }
            if (!CollectionUtils.isEmpty(dto.getNblteQuxians())) {
                List<Map<String, Object>> l = perCfgCellMapper.searchByCity(NetTypeEnum.NBLTE.name(),
                        dto.getNblteCitys(), dto.getNblteQuxians(), indicators, dto.getTimeType().name().toLowerCase(),
                        dto.getStartTime(), dto.getEndTime());
                list.addAll(l);
            }
            if (Boolean.TRUE.equals(dto.getIncludeOther())) {
                List<Map<String, Object>> l = perCfgCellMapper.others(indicators, dto.getTimeType().name(),
                        dto.getStartTime(), dto.getEndTime());
                list.addAll(l);
            }
        }
        // 按eci查询
        else if (SearchTypeEnum.ECI.equals(dto.getSearchType())) {
            String[] conditionArray = dto.getCondition().split(",");
            Set<String> conditions = Stream.of(conditionArray).collect(Collectors.toSet());
            list = perCfgCellMapper.searchByEci(conditions, indicators, dto.getTimeType().name().toLowerCase(),
                    dto.getStartTime(), dto.getEndTime());
        }
        // 汇聚查询
        else if (SearchTypeEnum.AGG.equals(dto.getSearchType())) {
            checkAreaPermission(dto, session);
            indicatorSet.remove("eci");
            indicatorSet.add("city");
            if (!CollectionUtils.isEmpty(dto.getLteCitys()) || !CollectionUtils.isEmpty(dto.getNblteCitys())) {
                indicators = String.join(",", indicatorSet);
                List<Map<String, Object>> l = perCfgCellMapper.aggByCity(Stream.concat(dto.getLteCitys().stream(),
                                dto.getNblteCitys().stream()).collect(Collectors.toSet()),
                        dto.getTimeType().name(), indicators, dto.getStartTime(), dto.getEndTime());
                list.addAll(l);
            }
            if (Boolean.TRUE.equals(dto.getIncludeOther())) {
                indicators = String.join(",", indicatorSet);
                List<Map<String, Object>> l = perCfgCellMapper.aggByOtherCity(dto.getTimeType().name().toLowerCase(),
                        indicators, dto.getStartTime(), dto.getEndTime());
                list.addAll(l);
            }
            indicatorSet.remove("city");
            indicatorSet.add("quxian");
            if (!CollectionUtils.isEmpty(dto.getLteQuxians()) || !CollectionUtils.isEmpty(dto.getNblteQuxians())) {
                indicators = String.join(",", indicatorSet);
                List<Map<String, Object>> l2 = perCfgCellMapper.aggByQuXian(Stream.concat(dto.getLteQuxians().stream(),
                                dto.getNblteQuxians().stream()).collect(Collectors.toSet()),
                        dto.getTimeType().name().toLowerCase(), indicators, dto.getStartTime(), dto.getEndTime());
                list.addAll(l2);
            }
            if (Boolean.TRUE.equals(dto.getIncludeOther())) {
                indicators = String.join(",", indicatorSet);
                List<Map<String, Object>> l = perCfgCellMapper.aggByOtherQuXian(dto.getTimeType().name().toLowerCase(),
                        indicators, dto.getStartTime(), dto.getEndTime());
                list.addAll(l);
            }
            indicatorSet.add("city");
            cols = getCols(indicatorSet);
        }
        return R.ok(new RetData(cols, list));
    }

    /**
     * 检查区域权限
     *
     * @param dto     dto
     * @param session 会话
     */
    private void checkAreaPermission(RenderTableDto dto, HttpSession session) {
        // 获取拥有的城市权限
        Map<String, String> areas = (Map<String, String>) session.getAttribute("areas");
        // 地区权限校验
        for (String t : dto.getLteCitys()) {
            if (!areas.containsKey(t)) {
                log.debug("没有权限的city: {}", t);
                throw new BizException("没有" + t + "的权限");
            }
        }
        for (String t : dto.getNblteCitys()) {
            if (!areas.containsKey(t)) {
                log.debug("没有权限的city: {}", t);
                throw new BizException("没有" + t + "的权限");
            }
        }
    }

    /**
     * 指标字段中英文map
     *
     * @return {@link Map}<{@link String}, {@link String}>
     */
    public Map<String, String> initZnEnMap() {
        Map<String, String> m = new LinkedHashMap<>();
        m.put("cellname", "小区中文名");
        m.put("province", "省");
        m.put("city", "地市");
        m.put("quxian", "区县");
        m.put("vendor", "厂家");
        List<PerCfgIndicator> indicators = perCfgIndicatorMapper.all();
        indicators.forEach(t -> m.put(t.getIndicatorEn(), t.getIndicatorCn()));
        return m;
    }

    /**
     * 得到宽度
     */
    Integer getWidth(String s) {
        int length = s.length();
        int width = length * 15;
        return Math.max(width, 200);
    }

    /**
     * 得到表头
     *
     * @param headers 头
     * @return {@link List}<{@link Col}>
     */
    List<Col> getCols(Set<String> headers) {
        List<Col> cols = new ArrayList<>();
        Map<String, String> ezMap = initZnEnMap();
        ezMap.forEach((k, v) -> {
            if (headers.contains(k)) {
                Col col = new Col();
                col.setField(k);
                col.setTitle(v);
                col.setWidth(getWidth(v));
                cols.add(col);
            }
        });
        return cols;
    }
}
