package com.njcn.device.pms.service.ledgerManger.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.device.pms.enums.PmsEnum;
import com.njcn.device.pms.mapper.majornetwork.PmsMidLedgerMapper;
import com.njcn.device.pms.mapper.majornetwork.PmsParkMapper;
import com.njcn.device.pms.pojo.dto.ParkDto;
import com.njcn.device.pms.pojo.param.PmsParkParam;
import com.njcn.device.pms.pojo.po.PmsMidLedger;
import com.njcn.device.pms.pojo.po.PmsParkPO;
import com.njcn.device.pms.pojo.po.PmsParkStationAss;
import com.njcn.device.pms.service.ledgerManger.IPmsParkService;
import com.njcn.device.pms.service.ledgerManger.IPmsParkStationAssService;
import com.njcn.user.api.DeptFeignClient;
import com.njcn.user.pojo.vo.PvTerminalTreeVO;
import com.njcn.web.enums.GWSendEnum;
import com.njcn.web.factory.PageFactory;
import com.njcn.web.pojo.param.SendParam;
import com.njcn.web.utils.GwSendUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 园区表 服务实现类
 * </p>
 *
 * @author cdf
 * @since 2024-06-19
 */
@Service
@RequiredArgsConstructor
public class PmsParkServiceImpl extends ServiceImpl<PmsParkMapper, PmsParkPO> implements IPmsParkService {

    private final DeptFeignClient deptFeignClient;

    private final IPmsParkStationAssService iPmsParkStationAssService;

    private final PmsMidLedgerMapper pmsMidLedgerMapper;




    @Override
    public Boolean addPark(PmsParkParam param) {
        PmsParkPO pmsParkPO = new PmsParkPO();
        BeanUtil.copyProperties(param, pmsParkPO);
        pmsParkPO.setIsDelete(DataStateEnum.ENABLE.getCode().toString());
        pmsParkPO.setUploadStatus(PmsEnum.NO_UPLOAD.getCode());
        List<PvTerminalTreeVO> dept = deptFeignClient.allDeptList().getData();
        getOrgCode(dept,pmsParkPO);
        return this.save(pmsParkPO);
    }

    @Override
    public Boolean updatePark(PmsParkParam.UpdatePmsParkParam updatePmsParkParam) {
        PmsParkPO result = this.getById(updatePmsParkParam.getObjId());
        PmsParkPO pmsParkPO = new PmsParkPO();
        BeanUtil.copyProperties(updatePmsParkParam, pmsParkPO);
        if(result.getUploadStatus().equals(PmsEnum.HAS_UPLOAD.getCode())){
            pmsParkPO.setUploadStatus(PmsEnum.WAIT_RETURN_UPLOAD.getCode());
        }
        List<PvTerminalTreeVO> dept = deptFeignClient.allDeptList().getData();
        getOrgCode(dept,pmsParkPO);
        return this.updateById(pmsParkPO);
    }

    @Override
    public Page<PmsParkPO> pageList(PmsParkParam.PmsParkQuery parkQuery) {
        List<String> deptCodes = deptFeignClient.getDepSonSelfCodetByDeptId(parkQuery.getMaintOrg()).getData();
        LambdaQueryWrapper<PmsParkPO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(PmsParkPO::getMaintOrg, deptCodes).orderByDesc(PmsParkPO::getCreateTime,PmsParkPO::getCityOrgName);
        return this.page(new Page<>(PageFactory.getPageNum(parkQuery), PageFactory.getPageSize(parkQuery)), lambdaQueryWrapper);
    }

    @Override
    public Boolean uploadParkGw(List<String> objIds) {
        List<PmsParkPO> pmsParkPOList;
        if(CollUtil.isEmpty(objIds)){
            LambdaQueryWrapper<PmsParkPO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.in(PmsParkPO::getUploadStatus, Stream.of(PmsEnum.NO_UPLOAD.getCode(),PmsEnum.WAIT_RETURN_UPLOAD.getCode()).collect(Collectors.toList()));
            pmsParkPOList =  this.list(lambdaQueryWrapper);
        }else {
            pmsParkPOList = this.listByIds(objIds);
        }
        List<String> ids = pmsParkPOList.stream().map(PmsParkPO::getObjId).collect(Collectors.toList());
        List<ParkDto.ParkSubstationRelVo> stationList = this.baseMapper.getParkStationAss(ids);

        List<ParkDto> dtoList = new ArrayList<>();
        ParkDto parkDto = new ParkDto();
        parkDto.setParkVoListt(pmsParkPOList);
        if(CollUtil.isNotEmpty(stationList)){
            parkDto.setParkSubstationRelVoList(stationList);
        }
        dtoList.add(parkDto);

        SendParam sendParam = new SendParam();
        sendParam.setStats(dtoList);
        Map<String,String> map = GwSendUtil.send(sendParam, GWSendEnum.PARK_AND_STATION);
        GwSendUtil.returnInfoMsg(objIds,map);

        LambdaUpdateWrapper<PmsParkPO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(PmsParkPO::getUploadStatus,PmsEnum.HAS_UPLOAD).eq(PmsParkPO::getObjId,objIds);
        this.update(updateWrapper);
        return true;
    }

    @Override
    public Page<PmsMidLedger> pageStationList(PmsParkParam.PmsParkQuery param) {
        Page<PmsMidLedger> result = new Page<>(param.getPageNum(),param.getPageSize());
         List<PmsParkStationAss> pmsParkStationAssList = iPmsParkStationAssService.list(new LambdaQueryWrapper<PmsParkStationAss>().eq(PmsParkStationAss::getParkId,param.getObjId()));
        List<String> ids = pmsParkStationAssList.stream().map(PmsParkStationAss::getMidStationId).collect(Collectors.toList());
        if(CollUtil.isEmpty(ids)){
            return result;
        }
        LambdaQueryWrapper<PmsMidLedger> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(PmsMidLedger::getId,ids);
        result = pmsMidLedgerMapper.selectPage(new Page<>(PageFactory.getPageNum(param),PageFactory.getPageSize(param)),lambdaQueryWrapper);
        return result;
    }

    @Override
    public List<PmsMidLedger> stationList(PmsParkParam.PmsParkQuery param) {
        List<String> ids = deptFeignClient.getDepSonSelfCodetByCode(param.getCityOrg()).getData();

        LambdaQueryWrapper<PmsMidLedger> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.select(PmsMidLedger::getName,PmsMidLedger::getOperationName,PmsMidLedger::getId).in(PmsMidLedger::getSectionId,ids).eq(PmsMidLedger::getLevel,0);
        List<PmsMidLedger> pmsMidLedgerList = pmsMidLedgerMapper.selectList(lambdaQueryWrapper);
        return pmsMidLedgerList;
    }


    private void getOrgCode(List<PvTerminalTreeVO> dept,PmsParkPO pmsParkPO){
        PvTerminalTreeVO pvTerminalTreeVO = dept.stream().filter(it->it.getCode().equals(pmsParkPO.getMaintOrg())).findFirst().orElse(null);
        if(Objects.nonNull(pvTerminalTreeVO)){
            if(pvTerminalTreeVO.getLevel() == 1 || pvTerminalTreeVO.getLevel() == 2){
                throw new BusinessException("请选择省级以下单位");
            }else if(pvTerminalTreeVO.getLevel() == 3){
                PvTerminalTreeVO province = dept.stream().filter(it->it.getId().equals(pvTerminalTreeVO.getPid())).findFirst().orElse(null);
                pmsParkPO.setCityOrg(pvTerminalTreeVO.getCode());
                pmsParkPO.setCityOrgName(pvTerminalTreeVO.getName());

                if(Objects.nonNull(province)){
                    pmsParkPO.setProvinceOrg(province.getCode());
                    pmsParkPO.setProvinceName(province.getName());
                }
            } else if(pvTerminalTreeVO.getLevel() == 4){
                PvTerminalTreeVO city = dept.stream().filter(it->it.getId().equals(pvTerminalTreeVO.getPid())).findFirst().orElse(null);
                if(Objects.nonNull(city)){
                    pmsParkPO.setCityOrg(city.getCode());
                    pmsParkPO.setCityOrgName(city.getName());

                    PvTerminalTreeVO province = dept.stream().filter(it->it.getId().equals(city.getPid())).findFirst().orElse(null);
                    if(Objects.nonNull(province)){
                        pmsParkPO.setProvinceOrg(province.getCode());
                        pmsParkPO.setProvinceName(province.getName());
                    }
                }

            }
        }

    }
}
