package com.ruoyi.report.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.report.domain.RzlClassStatisticsInfo;
import com.ruoyi.report.mapper.RzlClassStatisticsInfoMapper;
import com.ruoyi.report.service.IRzlClassStatisticsInfoService;
import com.ruoyi.report.vo.ClassStatisticsInfoVo;
import com.ruoyi.report.vo.ViewStatisticsInfoVo;
import com.ruoyi.system.domain.BladeRegion;
import com.ruoyi.system.service.IBladeRegionService;
import com.ruoyi.utils.BladeRegionUtils;

/**
 * 专利有效-分类统计Service业务层处理
 *
 * @author ruoyi
 * @date 2023-03-26
 */
@Service
public class RzlClassStatisticsInfoServiceImpl extends ServiceImpl<RzlClassStatisticsInfoMapper, RzlClassStatisticsInfo>
		implements IRzlClassStatisticsInfoService {
	@Autowired
	private IBladeRegionService bladeRegionService;
	@Autowired
	private RzlClassStatisticsInfoMapper rzlClassStatisticsInfoMapper;

	private void margeNotThisArea(List<Map> notThisAreaList, Map dataMap, Map<String, Map> alreadyNotThisArea,
			String areaCodeKey, String areaNameKey, String[] keys, String[] dataKeys) {
		StringBuffer keysb = new StringBuffer();
//		String areaCode = "000000";
		String areaCode = "非本区划";
		String areaName = "非本区划";
		keysb.append(areaCode).append("_").append(areaName);
		for (String key : keys) {
			String val = getStr(dataMap, key);
			if (StringUtils.isBlank(val)) {
				val = "null";
			}
			keysb.append("_").append(val);
		}
		if (!alreadyNotThisArea.containsKey(keysb.toString())) {
			Map newMap = new HashMap();
			newMap.putAll(dataMap);
			newMap.put(areaCodeKey, areaCode);
			newMap.put(areaNameKey, areaName);
			notThisAreaList.add(newMap);
			alreadyNotThisArea.put(keysb.toString(), newMap);
		} else {
			Map oldMap = alreadyNotThisArea.get(keysb.toString());
			for (String key : dataKeys) {
				long oldVal = getLong(oldMap, key);
				long newVal = getLong(dataMap, key);
				oldMap.put(key, oldVal + newVal);
			}
		}
	}
	
	
	
	private boolean isNotThisArea(Map map){
		Object obj=map.get("not_this_area");
		if(obj!=null) {
			return Boolean.parseBoolean(obj+"");
		}
		return false;
	}
	
	public Long sumByReport(RzlClassStatisticsInfo rzlClassStatisticsInfo) {
		return rzlClassStatisticsInfoMapper.sumByReport(rzlClassStatisticsInfo);
	}
	public List<ClassStatisticsInfoVo> listByReport(RzlClassStatisticsInfo rzlClassStatisticsInfo) {
		// TODO Auto-generated method stub
		String year = rzlClassStatisticsInfo.getYear();
		if (StringUtils.isBlank(year)) {
			year = "2022";
		}

		String cityCode = null;

		if (StringUtils.isNotBlank(rzlClassStatisticsInfo.getCityCode())
				&& !"53".equals(rzlClassStatisticsInfo.getCityCode())) {
			cityCode = rzlClassStatisticsInfo.getCityCode().trim();
			
			if(SecurityUtils.isNeedFilterByCityCode()) {
				String cc=SecurityUtils.needFilterByCityCode();
				if(!cc.equals(cityCode)) {
					return new ArrayList<ClassStatisticsInfoVo>();
				}
			}
			
		}else {
			if(SecurityUtils.isNeedFilterByCityCode()) {
				cityCode=SecurityUtils.needFilterByCityCode();
			}
		}
		rzlClassStatisticsInfo.setCityCode(cityCode);

		List<Map> mapList = rzlClassStatisticsInfoMapper.listByReport(rzlClassStatisticsInfo);

		// 处理非本区划
		boolean needSumNotThisArea = false;
		if (StringUtils.isNotBlank(cityCode)) {
			needSumNotThisArea = true;
		}
		List<Map> notThisAreaList = new ArrayList<Map>();
		Map<String, Map> alreadyNotThisArea = new HashMap<String, Map>();
		if (needSumNotThisArea && mapList != null && !mapList.isEmpty()) {
			BladeRegionUtils.setNotThisArea(mapList, cityCode);
			List<Map> newList = new ArrayList<Map>();
//			List<String> allCodes=bladeRegionService.getAllAreaCode();
//			Map<String,Boolean>alreadyMap=new HashMap<String,Boolean>();
			for (Map map : mapList) {
				String area_code = getStr(map, "area_code");
//				if (StringUtils.isBlank(area_code) || !area_code.startsWith(cityCode)) {
				if(isNotThisArea(map)) {
					// 合并到非本区化
					margeNotThisArea(notThisAreaList, map, alreadyNotThisArea, "area_code", "area_name",
							new String[] { "patent_type", "year" }, new String[] { "total_cnt", "higher_school",
									"research_institute", "enterprise", "institutions", "individual" });
				} else {
					newList.add(map);// 不是非本区划
				}
			}
			mapList = newList;
			mapList.addAll(notThisAreaList);
		}

//		List<RzlClassStatisticsInfoVo> list = new ArrayList<RzlClassStatisticsInfoVo>();

		ClassStatisticsInfoVo total = new ClassStatisticsInfoVo();
		total.setYear(year);
		total.setTotalCnt(0L);
		total.setHigherSchool(0L);
		total.setResearchInstitute(0L);
		total.setEnterprise(0L);
		total.setInstitutions(0L);
		total.setIndividual(0L);
		total.setPatentType("总计");
		if (rzlClassStatisticsInfo.getCityCode() == null || "null".equals(rzlClassStatisticsInfo.getCityCode().trim())
				|| "".equals(rzlClassStatisticsInfo.getCityCode().trim())) {
			total.setAreaName("云南省");
		} else {
			BladeRegion bladeRegion = BladeRegionUtils.selectByCode(rzlClassStatisticsInfo.getCityCode());
			if (bladeRegion != null) {
				total.setAreaName(bladeRegion.getName());
			}
		}
//		list.add(total);

		// key:area //20231022 key 改成用 areaCode
		Map<String, List<ClassStatisticsInfoVo>> areaMap = new LinkedHashMap<String, List<ClassStatisticsInfoVo>>();

		// key:areaName_type
		Map<String, ClassStatisticsInfoVo> areaTypeMap = new HashMap<String, ClassStatisticsInfoVo>();
		// key:type
		Map<String, ClassStatisticsInfoVo> typeTotalMap = new LinkedHashMap<String, ClassStatisticsInfoVo>();

		for (Map itemMap : mapList) {

			String areaName = null;

			StringBuffer sb = new StringBuffer();
//			if (itemMap.containsKey("area_name")) {
//				areaName = itemMap.get("area_name").toString();
//			} else {
//				areaName = "null";
//			}

			if (itemMap.containsKey("area_code")) {
				areaName = itemMap.get("area_code").toString();
			} else {
				areaName = "null";
			}
			
			sb.append(areaName);
			sb.append("_");

			String patentType = null;
			if (itemMap.containsKey("patent_type")) {
				patentType = itemMap.get("patent_type").toString();
			} else {
				patentType = "null";
			}
			sb.append(patentType);

			String alreadyKey = sb.toString();

			ClassStatisticsInfoVo vo = null;
			if (areaTypeMap.containsKey(alreadyKey)) {
				vo = areaTypeMap.get(alreadyKey);
			} else {
				vo = new ClassStatisticsInfoVo();
				// list.add(vo);
				vo.setPatentType(patentType);
				areaTypeMap.put(alreadyKey, vo);

				if (!areaMap.containsKey(areaName)) {
					List<ClassStatisticsInfoVo> areaList = new ArrayList<ClassStatisticsInfoVo>();
					areaMap.put(areaName, areaList);
					areaList.add(vo);
				} else {
					areaMap.get(areaName).add(vo);
				}

			}

			vo.setYear(year);
			vo.setPatentType(getStr(itemMap, "patent_type"));
			vo.setTotalCnt(vo.getTotalCnt() + getInt(itemMap, "total_cnt"));
			vo.setHigherSchool(vo.getHigherSchool() + getInt(itemMap, "higher_school"));
			vo.setResearchInstitute(vo.getResearchInstitute() + getInt(itemMap, "research_institute"));
			vo.setEnterprise(vo.getEnterprise() + getInt(itemMap, "enterprise"));
			vo.setInstitutions(vo.getInstitutions() + getInt(itemMap, "institutions"));
			vo.setIndividual(vo.getIndividual() + getInt(itemMap, "individual"));
//			vo.setAreaName(getStr(itemMap, "area_name"));
			vo.setAreaName(getStr(itemMap, "area_code"));

//			total.setTotalCnt(total.getTotalCnt() + vo.getTotalCnt());
//			total.setHigherSchool(total.getHigherSchool() + vo.getHigherSchool());
//			total.setResearchInstitute(total.getResearchInstitute() + vo.getResearchInstitute());
//			total.setEnterprise(total.getEnterprise() + vo.getEnterprise());
//			total.setInstitutions(total.getInstitutions() + vo.getInstitutions());
//			total.setIndividual(total.getIndividual() + vo.getIndividual());
			
			total.setTotalCnt(total.getTotalCnt() +getInt(itemMap, "total_cnt"));
			total.setHigherSchool(total.getHigherSchool() + getInt(itemMap, "higher_school"));
			total.setResearchInstitute(total.getResearchInstitute() + getInt(itemMap, "research_institute"));
			total.setEnterprise(total.getEnterprise() + getInt(itemMap, "enterprise"));
			total.setInstitutions(total.getInstitutions() + getInt(itemMap, "institutions"));
			total.setIndividual(total.getIndividual() + getInt(itemMap, "individual"));

//			list.add(vo);
//			TODO	
			// 总计
			ClassStatisticsInfoVo typeTotal = null;
			if (typeTotalMap.containsKey(patentType)) {
				typeTotal = typeTotalMap.get(patentType);
			} else {
				typeTotal = new ClassStatisticsInfoVo();

//				if(areaName==null || "null".equals(areaName.trim())  || "".equals(areaName.trim()) ) {
				typeTotal.setPatentType(patentType);
				total.setYear(year);
//				}

				typeTotalMap.put(patentType, typeTotal);
			}

//			typeTotal.setTotalCnt(typeTotal.getTotalCnt() + vo.getTotalCnt());
//			typeTotal.setHigherSchool(typeTotal.getHigherSchool() + vo.getHigherSchool());
//			typeTotal.setResearchInstitute(typeTotal.getResearchInstitute() + vo.getResearchInstitute());
//			typeTotal.setEnterprise(typeTotal.getEnterprise() + vo.getEnterprise());
//			typeTotal.setInstitutions(typeTotal.getInstitutions() + vo.getInstitutions());
//			typeTotal.setIndividual(typeTotal.getIndividual() + vo.getIndividual());
			
			typeTotal.setTotalCnt(typeTotal.getTotalCnt() + getInt(itemMap, "total_cnt"));
			typeTotal.setHigherSchool(typeTotal.getHigherSchool() +  getInt(itemMap, "higher_school"));
			typeTotal.setResearchInstitute(typeTotal.getResearchInstitute() + getInt(itemMap, "research_institute"));
			typeTotal.setEnterprise(typeTotal.getEnterprise() +getInt(itemMap, "enterprise"));
			typeTotal.setInstitutions(typeTotal.getInstitutions() + getInt(itemMap, "institutions"));
			typeTotal.setIndividual(typeTotal.getIndividual() + getInt(itemMap, "individual"));

		}

//		Collections.sort(list,new VoComparator());

		// 处理小计
		for (Map.Entry<String, List<ClassStatisticsInfoVo>> ent : areaMap.entrySet()) {
			List<ClassStatisticsInfoVo> areaList = ent.getValue();

			ClassStatisticsInfoVo tot = new ClassStatisticsInfoVo();
			tot.setAreaName(ent.getKey());
			tot.setPatentType("总计");
			for (ClassStatisticsInfoVo vo : areaList) {
				tot.setTotalCnt(tot.getTotalCnt() + vo.getTotalCnt());
				tot.setHigherSchool(tot.getHigherSchool() + vo.getHigherSchool());
				tot.setResearchInstitute(tot.getResearchInstitute() + vo.getResearchInstitute());
				tot.setEnterprise(tot.getEnterprise() + vo.getEnterprise());
				tot.setInstitutions(tot.getInstitutions() + vo.getInstitutions());
				tot.setIndividual(tot.getIndividual() + vo.getIndividual());
			}

			areaList.add(0, tot);

		}

		// 结果列表
		List<ClassStatisticsInfoVo> list = new ArrayList<ClassStatisticsInfoVo>();

		list.add(total);
		list.addAll(typeTotalMap.values());

		Collections.sort(list, new ClassStatisticsInfoVo());
		
		// 20231011 需要按指定顺序排序
		List<SortedData>sdList=new ArrayList<SortedData>();
		for (Map.Entry<String, List<ClassStatisticsInfoVo>> ent : areaMap.entrySet()) {
			
			String areaCode = ent.getKey();
			
			if (rzlClassStatisticsInfo.getCityCode() == null || "null".equals(rzlClassStatisticsInfo.getCityCode().trim())
					|| "".equals(rzlClassStatisticsInfo.getCityCode().trim())) {
				if(SecurityUtils.isNeedFilterByCityCode()) {
					String cc=SecurityUtils.needFilterByCityCode();
					if(!areaCode.equals(cc)) {
						continue;
					}
				}
			}else {
				
			}
			
			List<ClassStatisticsInfoVo> valList = ent.getValue();
			int sort = Integer.MAX_VALUE;// 默认排最后
			String areaName=areaCode;
			BladeRegion br = BladeRegionUtils.selectByCode(areaCode);
			if (br != null) {
				sort = br.getSort();
				areaName=br.getDistrictShortName();
			}
			SortedData sd = new SortedData(sort, areaName, valList);
			sdList.add(sd);
			
		}
		
		//排 序
		Collections.sort(sdList);

//		for (Map.Entry<String, List<ClassStatisticsInfoVo>> ent : areaMap.entrySet()) {
		for (SortedData d:sdList) {
			String areaName=d.areaName;
			List<ClassStatisticsInfoVo> list1 = d.dataList;
			List<ClassStatisticsInfoVo> shorted = getShortEd(list1);
			for (ClassStatisticsInfoVo vo : shorted) {
				vo.setAreaName(areaName);
				list.add(vo);
			}
		}
		
		for (ClassStatisticsInfoVo vo : list) {
			if (!"总计".equals(vo.getPatentType())) {
				vo.setAreaName("");
			}
		}
		
		

		return list;
	}
	
	private static class SortedData implements Comparable<SortedData> {
		private String areaName;
		private List<ClassStatisticsInfoVo> dataList;
		private int sort;

		private SortedData(int sort, String areaName, List<ClassStatisticsInfoVo> dataList) {
			this.areaName = areaName;
			this.dataList = dataList;
			this.sort=sort;
		}

		@Override
		public int compareTo(SortedData o) {
			return sort - o.sort;
		}
	}

	private List<ClassStatisticsInfoVo> getShortEd(Collection<ClassStatisticsInfoVo> voList) {
		List<ClassStatisticsInfoVo> list = new ArrayList<ClassStatisticsInfoVo>();
		if (voList != null) {
			list.addAll(voList);
		}
		Collections.sort(list, new ClassStatisticsInfoVo());
		return list;
	}

	private static class VoComparator implements Comparator<ClassStatisticsInfoVo> {

		@Override
		public int compare(ClassStatisticsInfoVo o1, ClassStatisticsInfoVo o2) {
			// TODO Auto-generated method stub
			int c = 0;
			if (o1.getAreaName() == null) {
				if (o2.getAreaName() == null) {
					c = 0;
				} else {
					return -1;
				}
			} else if (o2.getAreaName() != null) {
				c = o1.getAreaName().compareTo(o2.getAreaName());
			} else {
				c = 1;
			}

			if (c == 0) {
				if (o1.getPatentType() == null) {
					if (o2.getPatentType() == null) {
						c = 0;
					} else {
						return -1;
					}
				} else if (o2.getPatentType() != null) {
					c = o1.getPatentType().compareTo(o2.getPatentType());
				} else {
					c = 1;
				}
			}
			return 0;
		}

	}

	private String getStr(Map map, String key) {
		if (map == null || key == null || !map.containsKey(key)) {
			return "";
		}
		return map.get(key).toString().trim();
	}

	private long getLong(Map map, String key) {
		if (map == null || key == null || !map.containsKey(key)) {
			return 0L;
		}
		return Long.parseLong(map.get(key).toString());
	}

	private int getInt(Map map, String key) {
		if (map == null || key == null || !map.containsKey(key)) {
			return 0;
		}
		return Integer.parseInt(map.get(key).toString());
	}

	/**
	 * 查询专利有效-分类统计列表
	 *
	 * @param rzlClassStatisticsInfo 专利有效-分类统计
	 * @return 专利有效-分类统计集合
	 * @date 2023-03-26
	 */
	@Override
	public List<RzlClassStatisticsInfo> queryList(RzlClassStatisticsInfo rzlClassStatisticsInfo) {
		QueryWrapper<RzlClassStatisticsInfo> queryWrapper = Wrappers.query();
		if (StringUtils.isNotNull(rzlClassStatisticsInfo.getCityCode())) {
			queryWrapper.eq("city_code", rzlClassStatisticsInfo.getCityCode());
		}
		if (StringUtils.isNotEmpty(rzlClassStatisticsInfo.getCityName())) {
			queryWrapper.like("city_name", rzlClassStatisticsInfo.getCityName());
		}
		if (StringUtils.isNotEmpty(rzlClassStatisticsInfo.getYear())) {
			queryWrapper.eq("year", rzlClassStatisticsInfo.getYear());
		}
		if (StringUtils.isNotEmpty(rzlClassStatisticsInfo.getMonth())) {
			queryWrapper.eq("month", rzlClassStatisticsInfo.getMonth());
		}
		if (StringUtils.isNotEmpty(rzlClassStatisticsInfo.getPatentType())) {
			queryWrapper.eq("patent_type", rzlClassStatisticsInfo.getPatentType());
		}
		if (StringUtils.isNotEmpty(rzlClassStatisticsInfo.getApplicantType())) {
			queryWrapper.eq("applicant_type", rzlClassStatisticsInfo.getApplicantType());
		}
		if (StringUtils.isNotNull(rzlClassStatisticsInfo.getStatus())) {
			queryWrapper.eq("status", rzlClassStatisticsInfo.getStatus());
		}
		queryWrapper.orderByDesc("id");
		return this.list(queryWrapper);
	}

}
