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

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.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;
import io.swagger.models.auth.In;
import org.aspectj.weaver.ast.Var;
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 org.apache.commons.lang3.StringUtils;
import javax.annotation.Resource;
import java.util.*;
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;

    @Autowired
    DataDictionaryServiceImpl iDataDictionaryService;

    /**
     * 获取监控大队列表
     *
     * @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 -> {
            //递归返回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 bykongfm
            t.setFighterNum(getFightNumByTeamId(t.getSequenceNbr()));*/
        });
        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);
        // 机场单位
        //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);
        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 {
            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);
        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();

        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());
            }
        }
    }

}
