package com.huimv.env.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huimv.env.admin.common.utils.Result;
import com.huimv.env.admin.common.utils.ResultCode;
import com.huimv.env.admin.common.utils.ResultUtil;
import com.huimv.env.admin.entity.BasePigpen;
import com.huimv.env.admin.entity.Gateway;
import com.huimv.env.admin.entity.Terminal;
import com.huimv.env.admin.entity.TerminalPort;
import com.huimv.env.admin.entity.dto.BasePigpenDto;
import com.huimv.env.admin.entity.dto.ListPigpenDto;
import com.huimv.env.admin.entity.vo.TreeBasePigpen;
import com.huimv.env.admin.mapper.BasePigpenMapper;
import com.huimv.env.admin.mapper.GatewayMapper;
import com.huimv.env.admin.mapper.TerminalMapper;
import com.huimv.env.admin.mapper.TerminalPortMapper;
import com.huimv.env.admin.service.IBasePigpenService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-05-06
 */
@Service
public class BasePigpenServiceImpl extends ServiceImpl<BasePigpenMapper, BasePigpen> implements IBasePigpenService {
    @Autowired
    private BasePigpenMapper basePigpenMapper;
    @Autowired
    private GatewayMapper gatewayMapper;
    @Autowired
    private TerminalMapper terminalMapper;
    @Autowired
    private TerminalPortMapper portMapper;

    //    @Autowired
//    private EnvDeviceMapper envDeviceMapper;
//    @Autowired
//    private EnergyEnvDeviceMapper energyEnvDeviceMapper;
    @Override
    @Transactional
    public Result addPigpen(BasePigpenDto basePigpenDto) {
        Integer num = basePigpenMapper.selectCount(new QueryWrapper<BasePigpen>().eq("build_name", basePigpenDto.getBuildName())
                .eq("farm_id", basePigpenDto.getFarmId()).ne("other3", 1));
        if (num > 0) {
            return new Result(10001, "栋舍名称已存在！", false);
        }
        BasePigpen basePigpen = new BasePigpen();
        BeanUtil.copyProperties(basePigpenDto, basePigpen);
        basePigpen.setParentId(0);
        basePigpen.setFType(1);
        basePigpen.setOther2("0");
        int insert = basePigpenMapper.insert(basePigpen);
        Integer id = basePigpen.getId();
        String buildName = basePigpen.getBuildName();
        Integer floorNum = basePigpenDto.getFloorNum();
        Integer unitNum = basePigpenDto.getUnitNum();
        for (Integer integer = 1; integer <= unitNum; integer++) {
            BasePigpen basePigpen1 = new BasePigpen();
            basePigpen1.setFType(2);
            basePigpen1.setParentId(id);
            basePigpen1.setBuildName(buildName + Convert.numberToChinese(integer, false) + "单元");
            basePigpen1.setOther1(Convert.numberToChinese(integer, false) + "单元");
            basePigpen1.setOther2("0," + id);
            basePigpen1.setFarmId(basePigpen.getFarmId());
            basePigpen1.setStageCode(basePigpen.getStageCode());
            basePigpenMapper.insert(basePigpen1);
        }
        QueryWrapper<BasePigpen> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id", id);
        List<BasePigpen> basePigpens = basePigpenMapper.selectList(queryWrapper);
        for (BasePigpen pigpen : basePigpens) {
            for (Integer integer = 1; integer <= floorNum; integer++) {
                BasePigpen basePigpen1 = new BasePigpen();
                basePigpen1.setFType(3);
                basePigpen1.setParentId(pigpen.getId());
                basePigpen1.setBuildName(pigpen.getBuildName() + Convert.numberToChinese(integer, false) + "层");
                basePigpen1.setOther1(Convert.numberToChinese(integer, false) + "层");
                basePigpen1.setOther2(pigpen.getOther2()+","+pigpen.getId());
                basePigpen1.setFarmId(basePigpen.getFarmId());
                basePigpen1.setStageCode(basePigpen.getStageCode());
                basePigpenMapper.insert(basePigpen1);
            }
        }
        return ResultUtil.addResult(insert);
    }

    @Override
    @Transactional
    public Result updatePigpen(BasePigpen basePigpen) {
        Integer num = basePigpenMapper.selectCount(new QueryWrapper<BasePigpen>().eq("build_name", basePigpen.getBuildName())
                .eq("farm_id", basePigpen.getFarmId()).ne("id", basePigpen.getId()).ne("other3", 1));
        if (num > 0) {
            return new Result(10001, "栋舍名称已存在！", false);
        }
        basePigpenMapper.updateById(basePigpen);
        Integer id = basePigpen.getId();
        List<BasePigpen> parentId = basePigpenMapper.selectList(new QueryWrapper<BasePigpen>().eq("parent_id", id));
        String buildName = basePigpen.getBuildName();
        if (StringUtils.isNotBlank(buildName)) {
            for (BasePigpen pigpen : parentId) {
                String other1 = pigpen.getOther1();
                pigpen.setBuildName(buildName + other1);
                basePigpenMapper.updateById(pigpen);
            }
        }
        return ResultUtil.updateResult(1);
    }

    @Override
    @Transactional
    public Result deletePigpen(Map<String, Integer> map) {
        Integer integer = map.get("id");
        Integer count = gatewayMapper.selectCount(new QueryWrapper<Gateway>().eq("location_id", integer));
        if (count > 0) {
            return new Result(10001, "删除失败，该栋舍下有网关！", false);
        }
        List<BasePigpen> other2 = basePigpenMapper.selectList(new QueryWrapper<BasePigpen>().like("other2", integer));
        for (BasePigpen basePigpen : other2) {
            basePigpenMapper.deleteById(basePigpen.getId());
        }
        basePigpenMapper.deleteById(integer);
        return ResultUtil.deleteResult(1);
    }

    @Override
    public Result listPigpen(Map<String, Integer> map) {
        Integer farmId = map.get("farmId");
        return new Result(ResultCode.SUCCESS, basePigpenMapper.listPigpen(farmId));
    }

    @Override
    public Result deviceCount(Map<String, Integer> map) {
        Integer id = map.get("id");
        Integer onGateway = 0;
        Integer offGateway = 0;
        Integer onTerminal = 0;
        Integer offTerminal = 0;
//        Integer infoGateway = 0;//暂时不管
//        Integer infoTerminal = 0;//暂时不管
        Integer onPort = 0;
        Integer offPort = 0;
//        Integer infoPort = 0;
        Integer tempCount = 0;//高温报警
        Integer chargingCount = 0;//充电报警
        Integer leakageCount = 0;//漏电报警
        QueryWrapper<Gateway> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("location_id", id);
        List<Gateway> gateways = gatewayMapper.selectList(queryWrapper);
        for (Gateway gateway : gateways) {
            if (gateway.getStatus() == 0) {
                offGateway++;
            } else {
                onGateway++;
            }
        }
        List<Integer> idList = new ArrayList<>();
        gateways.forEach(item->{
            idList.add(item.getId());
        });
        if (idList.size() > 0) {
            QueryWrapper<Terminal> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.in("gateway_id", idList);
            List<Terminal> terminals = terminalMapper.selectList(queryWrapper1);
            for (Terminal terminal : terminals) {
                if (terminal.getStatus() == 0) {
                    offTerminal++;
                } else {
                    onTerminal++;
                }
            }
            List<Integer> idList2 = new ArrayList<>();
            terminals.forEach(item->{
                idList2.add(item.getId());
            });
            if (idList2.size() > 0) {
                QueryWrapper<TerminalPort> queryWrapper2 = new QueryWrapper<>();
                queryWrapper2.in("terminal_id", idList2);
                List<TerminalPort> terminalPorts = portMapper.selectList(queryWrapper2);
                for (TerminalPort terminal : terminalPorts) {
                    if (terminal.getLocationId() != null) {
                        if (terminal.getStatus() == 0) {
                            offPort++;
                        } else {
                            onPort++;
                        }
                        if (terminal.getHeightTempWarning() == 1) {
                            tempCount++;
                        }
                        if (terminal.getChargingWarning() == 1) {
                            chargingCount++;
                        }
                        if (terminal.getLeakageWarning() == 1) {
                            leakageCount++;
                        }
                    }
                }
            }
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("onGateway", onGateway);
        jsonObject.put("offGateway", offGateway);
        jsonObject.put("onTerminal", onTerminal);
        jsonObject.put("offTerminal", offTerminal);
//        jsonObject.put("infoGateway", infoGateway);//
//        jsonObject.put("infoTerminal", infoTerminal);//
        jsonObject.put("offPort", offPort);
        jsonObject.put("onPort", onPort);
        jsonObject.put("tempCount", tempCount);
        jsonObject.put("chargingCount", chargingCount);
        jsonObject.put("leakageCount", leakageCount);
//        jsonObject.put("infoPort", infoPort);
        return new Result(ResultCode.SUCCESS,jsonObject);
    }

    @Override
    public Result getGateway(Map<String, Integer> map) {
        Integer id = map.get("id");
        Integer pageNum = map.get("pageNum");
        Integer pageSize = map.get("pageSize");
        Page<Gateway> page = new Page(pageNum,pageSize);
        QueryWrapper<Gateway> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("location_id", id);
        return new Result(ResultCode.SUCCESS, gatewayMapper.selectPage(page,queryWrapper));
    }

    @Override
    public Result list(String farmCode, String buildName, String stageCode, String type) {
        QueryWrapper<BasePigpen> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(buildName), "build_name", buildName);
        queryWrapper.like(StringUtils.isNotBlank(stageCode), "stage_code", stageCode);
        queryWrapper.eq(StringUtils.isNotBlank(farmCode), "farm_id", farmCode);
        queryWrapper.eq("other3", type);
        queryWrapper.orderByAsc("id");
        //创建排序
        List<BasePigpen> basePigpens = basePigpenMapper.selectList(queryWrapper);
        //将结果List改为树
        List<TreeBasePigpen> treeBasePigpens = parseBizBaseArea(basePigpens);
        List<TreeBasePigpen> pigpens = jsonArraySort(treeBasePigpens, false);
        return new Result(ResultCode.SUCCESS, pigpens);
    }

    /**
     * 查询结果 转换成树形结构
     *
     * @param bizBaseAreas 原始数据
     * @return 树
     */
    private List<TreeBasePigpen> parseBizBaseArea(List<BasePigpen> bizBaseAreas) {
        //构建需要展示的树形节点结构
        Map<String, TreeBasePigpen> nodeMap = bizBaseAreas.stream().map(basePigpen -> {
            TreeBasePigpen baseVo = new TreeBasePigpen();
            baseVo.setId(basePigpen.getId() + "");
            baseVo.setFarmCode(basePigpen.getFarmId());
            baseVo.setParentId(basePigpen.getParentId());
            baseVo.setSort(basePigpen.getSort());
            baseVo.setLat(basePigpen.getLat());
            baseVo.setLng(basePigpen.getLng());
            baseVo.setStageCode(basePigpen.getStageCode());
            baseVo.setPigpenName(basePigpen.getBuildName());
            baseVo.setType(basePigpen.getFType());
            baseVo.setChildNode(new ArrayList<>());
            return baseVo;
        }).collect(Collectors.toMap(TreeBasePigpen::getId, b -> b, (k1, k2) -> k1));
        //创建数组存父亲节点
        ArrayList<TreeBasePigpen> roots = new ArrayList<>();
        //构建树形
        nodeMap.values().forEach(item -> {
            String parentCode = item.getParentId() + "";
            if (nodeMap.get(parentCode) == null) {
                //父节点为空，说明当前节点就已经是父节点了 将该节点存起来
                roots.add(item);
            } else {
                //父节点 不为空，说明有父节点，拿到该节点的父节点的孩子节点（就是我自己),将该节点存起来
                nodeMap.get(parentCode).getChildNode().add(item);
            }
        });
        return roots;
    }

    /*数组排序*/
    public static List<TreeBasePigpen> jsonArraySort(List<TreeBasePigpen> bizBaseAreas, boolean is_desc) {
        //存放排序结果json数组
        List<TreeBasePigpen> sortedJsonArray = new ArrayList<>();
        //用于排序的list

        List<TreeBasePigpen> jsonValues = new ArrayList<TreeBasePigpen>();
        //将参数json数组每一项取出，放入list
        for (int i = 0; i < bizBaseAreas.size(); i++) {
            jsonValues.add(bizBaseAreas.get(i));
        }
        //快速排序，重写compare方法，完成按指定字段比较，完成排序
        Collections.sort(jsonValues, new Comparator<TreeBasePigpen>() {
            //排序字段


            //重写compare方法
            @Override
            public int compare(TreeBasePigpen a, TreeBasePigpen b) {
                //如果用String接会导致一位数和两位数混合比对的时候不能准确比出来，要用int类型接
                //String valA = new String();
                //String valB = new String();
                Float valA = 0.00f;
                Float valB = 0.00f;
                try {
                    valA = Float.parseFloat(a.getId());
                    valB = Float.parseFloat(b.getId());
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                //是升序还是降序
                if (is_desc) {
                    return -valA.compareTo(valB);
                } else {
                    return -valB.compareTo(valA);
                }

            }
        });
        //将排序后结果放入结果jsonArray
        for (int i = 0; i < jsonValues.size(); i++) {
            sortedJsonArray.add(jsonValues.get(i));
        }

        return sortedJsonArray;
    }
}
