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

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.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 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 javax.annotation.Resource;
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;

/**
 * 消防队伍 服务实现类
 *
 * @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;

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

    /**
     * 消防队伍分页查询
     *
     * @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 -> {
            if (!ValidationUtil.isEmpty(finalTeamCarCountMap.get(t.getSequenceNbr().toString()))) {
                t.setCarNum(finalTeamCarCountMap.get(t.getSequenceNbr().toString()).intValue());
            }
        });
        fireTeamListPage.setRecords(fireTeamList);
        return fireTeamListPage;
    }

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

    public List<FireTeamDto> queryFireTeamForList(Boolean isDelete) {
        return fireTeamMapper.listFireTeamDto(isDelete);
    }

    /**
     * 根据列表构造队伍树
     *
     * @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);
        // 机场单位
        List<OrgUsr> companyDeptList = orgUsrService.selectCompanyDepartmentMsg();
        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);
        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 (ValidationUtil.isEmpty(fireTeam.getParent())) {
            fireTeam.setTreeCode(TreeParser.genTreeCode());
        } else {
            FireTeam parentTeam = getById(fireTeam.getParent());
            fireTeam.setTreeCode(parentTeam.getTreeCode() + TreeParser.genTreeCode());
        }
        if (ValidationUtil.isEmpty(fireTeam.getSequenceNbr())) {
            save(fireTeam);
        } else {
            updateById(fireTeam);
        }
        return fireTeam;
    }

    /**
     * 根据id删除队伍
     *
     * @param parent
     */
    public void deleteById(Long parent) throws Exception {
        // 查询是否有下属队伍
        List<FireTeamDto> fireTeamList = queryForList(null, false, parent);
        if (!ValidationUtil.isEmpty(fireTeamList) && fireTeamList.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();
        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;
        
    }
}
