package com.yeejoin.amos.boot.module.jcs.biz.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.typroject.tyboot.core.foundation.exception.BaseException;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yeejoin.amos.boot.biz.common.constants.BizConstant;
import com.yeejoin.amos.boot.biz.common.entity.BaseEntity;
import com.yeejoin.amos.boot.biz.common.entity.DataDictionary;
import com.yeejoin.amos.boot.biz.common.service.impl.DataDictionaryServiceImpl;
import com.yeejoin.amos.boot.biz.common.utils.Menu;
import com.yeejoin.amos.boot.biz.common.utils.MenuFrom;
import com.yeejoin.amos.boot.biz.common.utils.TreeParser;
import com.yeejoin.amos.boot.module.common.api.dto.FireBrigadeResourceDto;
import com.yeejoin.amos.boot.module.common.api.dto.FireTeamCardDto;
import com.yeejoin.amos.boot.module.common.api.dto.FireTeamDto;
import com.yeejoin.amos.boot.module.common.api.dto.FireTeamListDto;
import com.yeejoin.amos.boot.module.common.api.dto.FireTeamZhDto;
import com.yeejoin.amos.boot.module.common.api.dto.FirefightersDto;
import com.yeejoin.amos.boot.module.common.api.dto.RequestData;
import com.yeejoin.amos.boot.module.common.api.entity.FireTeam;
import com.yeejoin.amos.boot.module.common.api.entity.OrgUsr;
import com.yeejoin.amos.boot.module.common.api.feign.EquipFeignClient;
import com.yeejoin.amos.boot.module.common.api.mapper.FireTeamMapper;
import com.yeejoin.amos.boot.module.common.api.service.IFireTeamService;
import com.yeejoin.amos.boot.module.common.biz.service.impl.OrgUsrServiceImpl;
import com.yeejoin.amos.boot.module.common.biz.service.impl.WaterResourceServiceImpl;

/**
 * 消防队伍 服务实现类
 *
 * @author tb
 * @date 2021-06-07
 */
@Service
public class FireTeamServiceImpl extends BaseService<FireTeamDto, FireTeam, FireTeamMapper>
		implements IFireTeamService {

	@Resource
	FireTeamMapper fireTeamMapper;

	@Autowired
	EquipFeignClient equipFeignClient;

	@Autowired
	OrgUsrServiceImpl orgUsrService;

	@Autowired
	DataDictionaryServiceImpl iDataDictionaryService;

	/**
	 * 获取监控大队列表
	 *
	 * @return
	 */
	public List<FireBrigadeResourceDto> listMonitorFireBrigade(String code) {
		return fireTeamMapper.listMonitorFireBrigade(code);
	}

	/**
	 * 消防队伍分页查询
	 *
	 * @param page 分页对象
	 * @param team 查询参数
	 * @return
	 */
	public IPage<FireTeamCardDto> listFireTeamByPage(Page page, FireTeamListDto team) {
		// 获取消防车辆列表
		ResponseModel<Object> result = equipFeignClient.getFireCarListAll();
		Map<Object, Long> teamCarCountMap = Maps.newConcurrentMap();
		if (!ValidationUtil.isEmpty(result)) {
			List<Map<String, Object>> fireCarListMapList = (List<Map<String, Object>>) result.getResult();
			if (!ValidationUtil.isEmpty(fireCarListMapList)) {
				teamCarCountMap = fireCarListMapList.stream().filter(car -> !ValidationUtil.isEmpty(car.get("teamId")))
						.collect(Collectors.groupingBy(car -> car.get("teamId"), Collectors.counting()));
			}
		}

		// 查询单位
		if (Objects.equals("1", team.getNodeType())) {
			List<OrgUsr> companyDeptList = orgUsrService.listOrgUserById(team.getNodeId());
			team.setNodeIds(
					companyDeptList.stream().map(e -> e.getSequenceNbr().toString()).collect(Collectors.toList()));
		}
		// 查询队伍
		if (Objects.equals("0", team.getNodeType())) {
			List<FireTeam> teamList = listFireTeamById(team.getNodeId());
			team.setNodeIds(teamList.stream().map(e -> e.getSequenceNbr().toString()).collect(Collectors.toList()));
		}

		IPage<FireTeamCardDto> fireTeamListPage = this.baseMapper.getFireTeamForPage(page, team);
		List<FireTeamCardDto> fireTeamList = fireTeamListPage.getRecords();
		Map<Object, Long> finalTeamCarCountMap = teamCarCountMap;
		fireTeamList.forEach(t -> {
			// 递归返回teamId bug2684 bykongfm
			List<Long> teamIds = new ArrayList<Long>();
			getAllTeamId(teamIds, t.getSequenceNbr());
			int carNum = 0;
			int fighterNum = 0;
			for (Long tempId : teamIds) {
				if (finalTeamCarCountMap.get(tempId.toString()) != null) {
					carNum += finalTeamCarCountMap.get(tempId.toString()).intValue();
				}
				fighterNum += fireTeamMapper.getFighterNumByTeamId(tempId);
			}
			t.setCarNum(carNum);
			t.setFighterNum(fighterNum);
			/*
			 * //递归查找全部战备人数 BUG2217 bykongfmfirefighters/1435850387868385282
			 * t.setFighterNum(getFightNumByTeamId(t.getSequenceNbr()));
			 */
		});
		fireTeamListPage.setRecords(fireTeamList);
		return fireTeamListPage;
	}

	public List<FireTeam> listFireTeamById(Long teamId) {
		return this.baseMapper.listFireTeamById(teamId);
	}

	public List<FireTeamDto> queryFireTeamForListTree(Boolean isDelete) {
		return fireTeamMapper.listFireTeamDtoTree(isDelete);
	}
	public List<FireTeamDto> queryFireTeamForList(Boolean isDelete,Map map) {
		if(map== null || map.size()<1) {
			return fireTeamMapper.listFireTeamDto(isDelete,null,null,null,null,null);
		}
		String nodeId =map.containsKey("nodeId")?map.get("nodeId").toString():null;
		String nodeType =map.containsKey("nodeType")?map.get("nodeType").toString():null;
		String name =map.containsKey("name")?map.get("name").toString():null;
		String typeCode =map.containsKey("typeCode")?map.get("typeCode").toString():null;
		List<String> nodeIdsList=null;
		// 查询单位
		if (Objects.equals("1", nodeType)) {
			List<OrgUsr> companyDeptList = orgUsrService.listOrgUserById(Long.parseLong(nodeId));
			nodeIdsList = companyDeptList.stream().map(e -> e.getSequenceNbr().toString()).collect(Collectors.toList());
		}
		// 查询队伍
		if (Objects.equals("0", nodeType)) {
			List<FireTeam> teamList = listFireTeamById(Long.parseLong(nodeId));
			nodeIdsList = teamList.stream().map(e -> e.getSequenceNbr().toString()).collect(Collectors.toList());
		}
		return fireTeamMapper.listFireTeamDto(isDelete,nodeId,nodeType,name,typeCode,nodeIdsList);
	}
	/**
	 * 根据列表构造队伍树
	 *
	 * @param columnMap 查询列表条件
	 * @return 队伍树
	 * @throws Exception
	 */
	public List<Menu> getTeamTree(Map<String, Object> columnMap) throws Exception {
		Collection<FireTeam> list = this.listByMap(columnMap);
		return TreeParser.getTree(null, list, FireTeam.class.getName(), "getSequenceNbr", 2, "getName", "getParent",
				null);
	}

	/**
	 * 获取机场单位-队伍树
	 *
	 * @return
	 */
	public List<MenuFrom> getCompanyTeamTree() throws Exception {
		MenuFrom root = new MenuFrom("-1", "消防队伍", null, null);
		// 机场单位
		// bug:2457需求要求不显示部门，因此更换方法 by 陈浩 2021-08-18
		// List<OrgUsr> companyDeptList = orgUsrService.selectCompanyDepartmentMsg();
		List<OrgUsr> companyDeptList = orgUsrService.selectCompanyList();
		List<MenuFrom> companyDeptMenuList = Lists.newArrayList();
		companyDeptList.forEach(o -> {
			if (ValidationUtil.isEmpty(o.getParentId())) {
				o.setParentId("-1");
			}
			companyDeptMenuList
					.add(new MenuFrom(o.getSequenceNbr().toString(), o.getBizOrgName(), o.getParentId(), "1"));
		});
		// 消防队伍
		List<MenuFrom> teamMenuList = Lists.newArrayList();
		List<FireTeamDto> teamList = this.queryFireTeamForList(false,null);
		teamList.forEach(team -> {
			if (ValidationUtil.isEmpty(team.getParent())) {
				// 将单位下没有上级队伍的队伍直接挂在单位下（方便组成树结构）
				team.setParent(team.getCompany());
			}
			teamMenuList.add(
					new MenuFrom(team.getSequenceNbr().toString(), team.getName(), team.getParent().toString(), "0"));
		});
		companyDeptMenuList.addAll(teamMenuList);
		List<MenuFrom> menuList = TreeParser.getTreexin("-1", companyDeptMenuList, MenuFrom.class.getName(), "getKey",
				1, "getName", "getParentId", "getNodeType");
		root.setChildren(menuList);
		return Lists.newArrayList(root);
	}

	/**
	 * 根据队伍id查询队伍下人员列表
	 *
	 * @param teamIds
	 * @return
	 */
	public List<FirefightersDto> getFighterByTeamId(List<String> teamIds) {
		return this.baseMapper.queryFighterByTeamId(teamIds);
	}

	public FireTeam saveFireTeam(FireTeam fireTeam) {

		if (fireTeam.getAddress() != null) {
			JSONObject address = WaterResourceServiceImpl.getLongLatFromAddress(fireTeam.getAddress());
			fireTeam.setAddress(address.getString(BizConstant.ADDRESS));
			fireTeam.setLongitude(Double.valueOf(address.getString(BizConstant.LONGITUDE)));
			fireTeam.setLatitude(Double.valueOf(address.getString(BizConstant.LATITUDE)));
		}
		if (ValidationUtil.isEmpty(fireTeam.getParent())) {
			fireTeam.setTreeCode(TreeParser.genTreeCode());
		} else {
			FireTeam parentTeam = getById(fireTeam.getParent());
			fireTeam.setTreeCode(parentTeam.getTreeCode() + TreeParser.genTreeCode());
		}

		DataDictionary dataDictionary = iDataDictionaryService.getById(fireTeam.getTypeCode());
		if (null != dataDictionary) {
			fireTeam.setType(dataDictionary.getName());
		}
		if (ValidationUtil.isEmpty(fireTeam.getSequenceNbr())) {
			save(fireTeam);
		} else {
			/*如果修改的队伍有下级队伍，所属单位一起修改 2021-10-18 陈召 开始*/
			LambdaQueryWrapper<FireTeam> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(FireTeam::getParent,fireTeam.getSequenceNbr());
			wrapper.eq(BaseEntity::getIsDelete,false);
			List<FireTeam> fireTeams = baseMapper.selectList(wrapper);
			if (!fireTeams.isEmpty()){
				fireTeams.forEach(i->{
					i.setCompany(fireTeam.getCompany());
					i.setCompanyName(fireTeam.getCompanyName());
					i.setCompanyCode(fireTeam.getCompanyCode());
					updateById(i);
				});
			}
			/*如果修改的队伍有下级队伍，所属单位一起修改 2021-10-18 陈召 结束*/
			updateById(fireTeam);
		}
		return fireTeam;
	}

	public static JSONObject getLongLatFromAddress(String address) {
		JSONObject result = new JSONObject();
		result.put(BizConstant.ADDRESS, "");
		result.put(BizConstant.LONGITUDE, "0");
		result.put(BizConstant.LATITUDE, "0");
		if (StringUtils.isNotEmpty(address)) {
			String[] addressData = address.split("@address@");
			if (addressData.length > 1) {
				result.put(BizConstant.ADDRESS, addressData[0]);
				JSONObject langLatObj = JSON.parseObject(addressData[1]);
				if (StringUtils.isNotEmpty(langLatObj.getString(BizConstant.LONGITUDE))) {
					result.put(BizConstant.LONGITUDE, langLatObj.getString(BizConstant.LONGITUDE));
				} else {
					result.put(BizConstant.LONGITUDE, "0");
				}
				if (StringUtils.isNotEmpty(langLatObj.getString(BizConstant.LATITUDE))) {
					result.put(BizConstant.LATITUDE, langLatObj.getString(BizConstant.LATITUDE));
				} else {
					result.put(BizConstant.LATITUDE, "0");
				}
			} else {
				result.put(BizConstant.ADDRESS, addressData[0]);
			}
		}
		return result;
	}

	/**
	 * 根据id删除队伍
	 *
	 * @param parent
	 */
	public void deleteById(Long parent) throws Exception {
		// 查询是否有下属队伍
		// List<FireTeamDto> fireTeamList = queryForList(null, false, parent);
		/* 3026 【web】日常管理>机场单位，删除有级联数据的部门时，应无法直接删除 chenzhao 2021-09-28 start */
		LambdaQueryWrapper<FireTeam> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(FireTeam::getParent, parent);
		wrapper.eq(BaseEntity::getIsDelete, 0);
		List<FireTeam> fireTeams = baseMapper.selectList(wrapper);
		/* 3026 【web】日常管理>机场单位，删除有级联数据的部门时，应无法直接删除 chenzhao 2021-09-28 end */
		if (!ValidationUtil.isEmpty(fireTeams) && fireTeams.size() > 0) {
			// 有下属队伍不能删除
			throw new BaseException("该队伍下有下级队伍，不能删除", null, "该队伍下有下级队伍，不能删除");
		}
		update(new UpdateWrapper<FireTeam>().eq("sequence_nbr", parent).set("is_delete", 1));
	}

	@Override
	public List<FireTeamZhDto> getFireTeamList(Integer pageNum, Integer pageSize, RequestData par) {

		if (null == pageNum || null == pageSize) {
			pageNum = 1;
			pageSize = Integer.MAX_VALUE;
		} else {
			pageNum = (pageNum - 1) * pageSize;
		}

		List<FireTeamZhDto> list = fireTeamMapper.getFireTeamList(pageNum, pageSize, par);

		// 获取消防车辆列表
		ResponseModel<List<Map<String, Object>>> result = equipFeignClient.getFireCarListAllcount();

		List<Map<String, Object>> result1 = result.getResult();

		list.forEach(fireTeamZhDto -> {
			Long sequenceNbr = fireTeamZhDto.getSequenceNbr();
			result1.forEach(map -> {
				String mapId = String.valueOf(map.get("teamId"));
				if (String.valueOf(sequenceNbr).equals(mapId)) {
					Integer carNum = Integer.valueOf(map.get("carNum").toString());
					fireTeamZhDto.setCarNum(carNum);
				}
			});
		});
		/*
		 * 
		 * if(result1!=null&&result1.size()>0){ Map<String, Object> combineResultMap =
		 * new HashMap<String, Object>(); result1.stream().forEach(obj ->{
		 * combineResultMap.put(obj.get("teamId").toString(),obj.get("carNum")); });
		 * list.stream().forEach(obj ->{
		 * if(combineResultMap.containsKey(obj.getSequenceNbr())){
		 * obj.setCarNum(Integer.valueOf(combineResultMap.get(obj.getSequenceNbr()).
		 * toString())); } }); }
		 */
		return list;
	}

	@Override
	public Integer getFireTeamListCount(RequestData par) {

		return fireTeamMapper.getFireTeamListCount(par);
	}

	@Override
	public FireTeam getFireTeamBySequenceNbr(Long id) {
		return this.getById(id);
	}

	@Override
	public List<FireTeamZhDto> getFireTeamCountList() {
		List<FireTeamZhDto> list = fireTeamMapper.getFireTeamCountList();

		// 获取消防车辆列表
		ResponseModel<List<Map<String, Object>>> result = equipFeignClient.getFireCarListAllcount();

		List<Map<String, Object>> result1 = result.getResult();
		if (result1 != null && result1.size() > 0) {
			Map<String, Object> combineResultMap = new HashMap<String, Object>();
			result1.stream().forEach(obj -> {
				combineResultMap.put(obj.get("teamId").toString(), obj.get("carNum"));
			});
			list.stream().forEach(obj -> {
				if (combineResultMap.containsKey(obj.getSequenceNbr().toString())) {
					obj.setCarNum(Integer.valueOf(combineResultMap.get(obj.getSequenceNbr().toString()).toString()));
				}
			});
		}

		return list;

	}

	public Integer getFightNumByTeamId(Long teamId) {
		Integer count = 0;
		// 获取自己的数据
		count += fireTeamMapper.getFighterNumByTeamId(teamId);
		// 获取下部分数据
		LambdaQueryWrapper<FireTeam> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(FireTeam::getParent, teamId).eq(FireTeam::getIsDelete, false);
		List<FireTeam> fireTeamList = this.list(queryWrapper);
		if (fireTeamList.size() == 0) {
			return count;
		} else {
			for (FireTeam t : fireTeamList) {
				count += getFightNumByTeamId(t.getSequenceNbr());
			}
		}
		// 获取子集数据
		return count;
	}

	public void getAllTeamId(List<Long> teamIds, Long teamId) {
		teamIds.add(teamId);
		LambdaQueryWrapper<FireTeam> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(FireTeam::getParent, teamId).eq(FireTeam::getIsDelete, false);
		List<FireTeam> fireTeamList = this.list(queryWrapper);
		if (fireTeamList.size() == 0) {
			// 没有下级单位
		} else {
			for (FireTeam t : fireTeamList) {
				getAllTeamId(teamIds, t.getSequenceNbr());
			}
		}
	}

	/**
	 * 加载系统中本单位消防队伍中类型为【企（事）业单位医疗救援队（站）】的队伍  --->急救站
	 * @param typeCode
	 */
	public List<FireTeam> getFirstAidForTypeCodeAndCompanyId(String dicCode,String typeCode,Long companyId) {
		DataDictionary dataDictionary = iDataDictionaryService.getByCode(dicCode,typeCode);
		if (ObjectUtils.isEmpty(dataDictionary)) {
			return null;
		}
		String code =	dataDictionary.getCode();
		LambdaQueryWrapper<FireTeam> queryWrapper = new LambdaQueryWrapper<FireTeam>();
		queryWrapper.eq(FireTeam::getTypeCode, code);
		queryWrapper.eq(FireTeam::getIsDelete, false);
		queryWrapper.eq(FireTeam::getCompany, companyId);
		return	this.baseMapper.selectList(queryWrapper);
	}
}
