package cn.cecep.talroad.service.impl;

import cn.cecep.talroad.common.core.domain.R;
import cn.cecep.talroad.common.core.utils.DateUtils;
import cn.cecep.talroad.common.core.utils.StringUtils;
import cn.cecep.talroad.common.security.utils.SecurityUtils;
import cn.cecep.talroad.domain.AmVideoDevFi;
import cn.cecep.talroad.domain.BasDevice;
import cn.cecep.talroad.domain.MAmVideoInfoOperationLog;
import cn.cecep.talroad.enums.OperationTypeEnum;
import cn.cecep.talroad.feign.BaseRegionService;
import cn.cecep.talroad.mapper.AmVideoDevFiMapper;
import cn.cecep.talroad.mapper.BasDeviceMapper;
import cn.cecep.talroad.mapper.MAmVideoInfoOperationLogMapper;
import cn.cecep.talroad.service.IAmVideoDevFiService;
import cn.cecep.talroad.system.api.domain.SysUser;
import cn.cecep.talroad.vo.AmVideoDevFiVo;
import cn.cecep.talroad.vo.EChartsVO;
import cn.cecep.talroad.vo.export.AmVideoDevFiExport;
import cn.cecep.talroad.vo.homepage.OverviewVideoMonitorsVo;
import cn.cecep.talroad.vo.homepage.ProportionVideoMonitorsVo;
import cn.cecep.talroad.vo.homepage.VideoMonitoringIssuesVo;
import cn.cecep.talroad.vo.query.AmVideoDevFiQuery;
import cn.cecep.talroad.vo.query.EffectiveMonitoringRateQuery;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 视频监控Service业务层处理
 *
 * @author szhpt
 * @date 2023-01-10*/
@Service
@Slf4j
public class AmVideoDevFiServiceImpl extends ServiceImpl<AmVideoDevFiMapper,AmVideoDevFi> implements IAmVideoDevFiService
{
    @Autowired
    private AmVideoDevFiMapper amVideoDevFiMapper;

    @Autowired
    private BasDeviceMapper basDeviceMapper;


    /**
     * 查询视频监控列表
     *
     * @param amVideoDevFi 视频监控
     * @return 视频监控
     */
    @Override
    public List<AmVideoDevFi> selectAmVideoDevFiList(AmVideoDevFi amVideoDevFi)
    {
        return amVideoDevFiMapper.selectAmVideoDevFiList(amVideoDevFi);
    }
    @Override
    public List<AmVideoDevFiExport> selectAmVideoDevFiExportList(AmVideoDevFi amVideoDevFi)
    {
        return amVideoDevFiMapper.selectAmVideoDevFiExportList(amVideoDevFi);
    }

    @Override
    public List<AmVideoDevFiExport> selectAmVideoDevFiSelectList(@Param("ew") QueryWrapper<AmVideoDevFi> queryWrapper)
    {
        return amVideoDevFiMapper.selectAmVideoDevFiSelectList(queryWrapper);
    }

    @Override
    public List<AmVideoDevFiExport> selectAmVideoDevFiSelectXkList(@Param("ew") QueryWrapper<AmVideoDevFi> queryWrapper)
    {
        return amVideoDevFiMapper.selectAmVideoDevFiSelectXkList(queryWrapper);
    }

    @Autowired
    private MAmVideoInfoOperationLogMapper mAmVideoInfoOperationLogMapper;

    @Autowired
    @Qualifier("baseRegionService")
    private BaseRegionService baseRegionService;
    /**
     * 2023年4月30日12:15:46
     * 郝庆玉
     * @param amVideoDevFi
     * @return 视频设备修改排污许可设备信息记录日志
     */
    @Override
    public IPage<MAmVideoInfoOperationLog> getMAmVideoInfoOperationLogList(AmVideoDevFiQuery amVideoDevFi)
    {
        Page<MAmVideoInfoOperationLog> page = new Page<>(amVideoDevFi.getPageNum(), amVideoDevFi.getPageSize());
        List<MAmVideoInfoOperationLog> list = mAmVideoInfoOperationLogMapper.selectListByParam(page, amVideoDevFi,
                org.apache.commons.lang3.StringUtils.isEmpty(amVideoDevFi.getStartTime()) ? null : Timestamp.valueOf(amVideoDevFi.getStartTime()),
                org.apache.commons.lang3.StringUtils.isEmpty(amVideoDevFi.getEndTime()) ? null : Timestamp.valueOf(amVideoDevFi.getEndTime()));
        page.setRecords(list);
        return page;
    }


    @Override
    public IPage<AmVideoDevFiExport> selectDeviceNameById(Page<AmVideoDevFi> page, @Param("ew") QueryWrapper<AmVideoDevFi> queryWrapper){
        return amVideoDevFiMapper.selectDeviceNameById(page,queryWrapper);
    }

    @Override
    public List<AmVideoDevFiVo.DevTypeGroup> getGroupList(AmVideoDevFiQuery amVideoDevFi) {
        List<AmVideoDevFiVo> videoDevFis = list(AmVideoDevFiQuery.createLambdaQueryWrapper(amVideoDevFi))
                .stream().map(o -> {
                    AmVideoDevFiVo vo = new AmVideoDevFiVo();
                    BeanUtils.copyProperties(o, vo);
                    return vo;
                }).collect(Collectors.toList());
        if (videoDevFis.isEmpty()) {
            return new ArrayList<>();
        }
        return group(videoDevFis);
    }

    @Override
    public List<AmVideoDevFiVo.DevTypeGroup> getGroupList(String factoryId, String outletId, List<String> deviceIds) {
        // 根据产治排的设备，找到关联的排污许可设备
        List<String> xkDeviceIds = null;

        if (CollectionUtils.isNotEmpty(deviceIds)) {
            List<BasDevice> basDevices = basDeviceMapper.selectBatchIds(deviceIds);
            if (basDevices.size() > 0) {
                Set<String> pollutantCodes = new HashSet<>();
                for (BasDevice basDevice : basDevices) {
                    if (basDevice.getElecdcsPollutantRelations() != null) {
                        String[] split = basDevice.getElecdcsPollutantRelations().split(",");
                        for (String s : split) {
                            if (StringUtils.isNotBlank(s)) {
                                pollutantCodes.add(s);
                            }
                        }
                    }
                }
                List<BasDevice> xvDevList = basDeviceMapper.selectList(new QueryWrapper<BasDevice>().eq("factory_id", factoryId).in("pollutant_code", pollutantCodes));
                xkDeviceIds = xvDevList.stream().map(BasDevice::getDeviceId).collect(Collectors.toList());
            }
        }
        if (StringUtils.isBlank(outletId) && CollectionUtils.isEmpty(xkDeviceIds)) {
            return new ArrayList<>();
        }
        List<AmVideoDevFiVo> videoDevFis = amVideoDevFiMapper.selectByOutletAndDeviceIds(outletId, xkDeviceIds);
        return group(videoDevFis);
    }

    private List<AmVideoDevFiVo.DevTypeGroup> group(List<AmVideoDevFiVo> videoDevFis) {
        // 视频分组
        return videoDevFis.stream()
                .collect(Collectors.groupingBy(o -> StringUtils.isBlank(o.getDevType()) ? "默认分组" : o.getDevType(), LinkedHashMap::new, Collectors.toList()))
                .entrySet().stream().map(o -> {
                    AmVideoDevFiVo.DevTypeGroup group = new AmVideoDevFiVo.DevTypeGroup();
                    group.setName(o.getKey());
                    group.setVideoDevFiVos(o.getValue());
                    return group;
                }).collect(Collectors.toList());
    }

    @Override
    public AmVideoDevFiVo getInfo(Long id) {
        AmVideoDevFi source = getById(id);
        AmVideoDevFiVo vo = new AmVideoDevFiVo();
        BeanUtils.copyProperties(source, vo);
        return vo;
    }

    /**
     * 2023年4月30日12:10:16
     * @Auth hqy
     *  视频绑定排污许可设备日志信息
     * @param aeList
     * @param adList
     */
    @Override
    public void saveLog(List<AmVideoDevFiExport> aeList, List<AmVideoDevFiExport> adList) {
        List<MAmVideoInfoOperationLog> list = new ArrayList<>();
        SysUser sysUser = SecurityUtils.getLoginUser().getSysUser();
        Date date = new Date();
        for(int i =0;i<aeList.size();i++){
            MAmVideoInfoOperationLog mAmVideoInfoOperationLog = new MAmVideoInfoOperationLog();
            mAmVideoInfoOperationLog.setLogId(UUID.randomUUID().toString().trim().replaceAll("-", ""));
            mAmVideoInfoOperationLog.setOperationTime(DateUtils.parseFormatDate("yyyy-MM-dd HH:mm:ss",date));
            // 视频设施名称
            mAmVideoInfoOperationLog.setVideoStationName(adList.get(i).getDevName());
            if(adList.get(i).getChannelId()!=null && !"".equals(adList.get(i).getChannelId())){
                mAmVideoInfoOperationLog.setVideoChannel(adList.get(i).getChannelId());
            }else{
                mAmVideoInfoOperationLog.setVideoChannel(adList.get(i).getId().toString());
            }
            // 修改前对应许可证生产设施名称
            mAmVideoInfoOperationLog.setBeforeModifyName(adList.get(i).getOutletName());
            // 修改前对应许可证生产设施编号
            mAmVideoInfoOperationLog.setBeforeModifyCode(adList.get(i).getOutletCode());
            String sta = "";
            if(!org.apache.commons.lang3.StringUtils.isEmpty(adList.get(i).getDeviceId()) && !org.apache.commons.lang3.StringUtils.isEmpty(aeList.get(i).getDeviceId())){
                sta = OperationTypeEnum.UPDATE_OPERATION.getName();
            }else if(!org.apache.commons.lang3.StringUtils.isEmpty(adList.get(i).getDeviceId()) && org.apache.commons.lang3.StringUtils.isEmpty(aeList.get(i).getDeviceId())){
                sta = OperationTypeEnum.CANCEL_THE_CORRESPONDENCE.getName();
            }else{
                sta = OperationTypeEnum.INSERT_OPERATION.getName();
            }
            // 操作状态
            mAmVideoInfoOperationLog.setOperationStatus(sta);
            // 修改后对应许可证生产设施编号
            mAmVideoInfoOperationLog.setAfterModifyCode(aeList.get(i).getOutletCode());
            // 修改后对应许可证生产设施名称
            mAmVideoInfoOperationLog.setAfterModifyName(aeList.get(i).getOutletName());
            // 操作人
            mAmVideoInfoOperationLog.setOperator(sysUser.getNickName());
            // 操作人ID
            mAmVideoInfoOperationLog.setOperatorId(String.valueOf(sysUser.getUserId()));
            // 企业ID
            mAmVideoInfoOperationLog.setFactoryId(adList.get(i).getFactoryId());
            list.add(mAmVideoInfoOperationLog);
        }
        mAmVideoInfoOperationLogMapper.batchInsert(list);
    }

    @Override
    public AmVideoDevFiExport getByExport(BigInteger id) {
        return amVideoDevFiMapper.getByExport(id);
    }

    @Override
    public OverviewVideoMonitorsVo overviewVideoMonitors() {
        String regionCode = SecurityUtils.getLoginUser().getSysUser().getRegionCode();

        List<String> regionCodes=new ArrayList<>();
        R<List<String>> r = baseRegionService.getRegionCodeListChild(regionCode);
        if(r.getCode()==200){
            regionCodes=r.getData();
        }
        OverviewVideoMonitorsVo monitorsVo=new OverviewVideoMonitorsVo();
        monitorsVo.setVideoEnterprise(amVideoDevFiMapper.overviewVideoMonitors("1",regionCodes));
        monitorsVo.setVideoNumber(amVideoDevFiMapper.overviewVideoMonitors("2", regionCodes));
        monitorsVo.setAccessControlEnterprise(amVideoDevFiMapper.overviewVideoMonitors("3", regionCodes));
        monitorsVo.setAccessControlNumber(amVideoDevFiMapper.overviewVideoMonitors("4", regionCodes));
        return monitorsVo;
    }

    @Override
    public EChartsVO proportionExitTypes(EffectiveMonitoringRateQuery query) {
        String regionCode = SecurityUtils.getLoginUser().getSysUser().getRegionCode();

        List<String> regionCodes=new ArrayList<>();
        R<List<String>> r = baseRegionService.getRegionCodeListChild(regionCode);
        if(r.getCode()==200){
            regionCodes=r.getData();
        }
        query.setRegionCodes(regionCodes);
        ProportionVideoMonitorsVo monitorsVo=amVideoDevFiMapper.proportionExitTypes(query);
        BigDecimal total = monitorsVo.getVideoNumber().add(monitorsVo.getVideoEnterprise()).add(monitorsVo.getAccessControlEnterprise()).add(monitorsVo.getAccessControlNumber());
        EChartsVO eChartsVO=new EChartsVO();
        List<EChartsVO.SeriesObj> items= new ArrayList<>();
        EChartsVO.SeriesObj ser = new EChartsVO.SeriesObj();
        ser.setName("新能源");
        ser.setValues(new ArrayList<>());
        if(total.compareTo(BigDecimal.ZERO)>0){
            ser.setUnit(monitorsVo.getVideoEnterprise().divide(total,4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)).stripTrailingZeros().toPlainString()+"%");
        }else {
            ser.setUnit("0%");
        }
        items.add(ser);
        EChartsVO.SeriesObj ser1 = new EChartsVO.SeriesObj();
        ser1.setName("国六");
        ser1.setValues(new ArrayList<>());
        if(total.compareTo(BigDecimal.ZERO)>0) {
            ser1.setUnit(monitorsVo.getVideoNumber().divide(total, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)).stripTrailingZeros().toPlainString() + "%");
        }else {
            ser1.setUnit("0%");
        }
        items.add(ser1);
        EChartsVO.SeriesObj ser2 = new EChartsVO.SeriesObj();
        ser2.setName("国五");
        ser2.setValues(new ArrayList<>());
        if(total.compareTo(BigDecimal.ZERO)>0) {
            ser2.setUnit(monitorsVo.getAccessControlEnterprise().divide(total, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)).stripTrailingZeros().toPlainString() + "%");
        }else {
            ser2.setUnit("0%");
        }
        items.add(ser2);
        EChartsVO.SeriesObj ser3 = new EChartsVO.SeriesObj();
        ser3.setName("国四及以下");
        ser3.setValues(new ArrayList<>());
        if(total.compareTo(BigDecimal.ZERO)>0) {
            ser3.setUnit(monitorsVo.getAccessControlNumber().divide(total, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100)).stripTrailingZeros().toPlainString() + "%");
        }else {
            ser3.setUnit("0%");
        }
        items.add(ser3);
        items.get(0).getValues().add(monitorsVo.getVideoEnterprise());
        items.get(1).getValues().add(monitorsVo.getVideoNumber());
        items.get(2).getValues().add(monitorsVo.getAccessControlEnterprise());
        items.get(3).getValues().add(monitorsVo.getAccessControlNumber());
        eChartsVO.setSeries(items);
        return eChartsVO;
    }

    @Override
    public EChartsVO trendsVehicleEmissionTypes(EffectiveMonitoringRateQuery query) {
        String regionCode = SecurityUtils.getLoginUser().getSysUser().getRegionCode();

        List<String> regionCodes=new ArrayList<>();
        R<List<String>> r = baseRegionService.getRegionCodeListChild(regionCode);
        if(r.getCode()==200){
            regionCodes=r.getData();
        }
        query.setRegionCodes(regionCodes);
        List<OverviewVideoMonitorsVo> monitorsVo=amVideoDevFiMapper.trendsVehicleEmissionTypes(query);
        EChartsVO eChartsVO=new EChartsVO();
        List<EChartsVO.SeriesObj> items= new ArrayList<>();
        EChartsVO.SeriesObj ser = new EChartsVO.SeriesObj();
        ser.setName("新能源");
        ser.setUnit("辆");
        ser.setValues(new ArrayList<>());
        items.add(ser);
        EChartsVO.SeriesObj ser1 = new EChartsVO.SeriesObj();
        ser1.setName("国六");
        ser1.setUnit("辆");
        ser1.setValues(new ArrayList<>());
        items.add(ser1);
        EChartsVO.SeriesObj ser2 = new EChartsVO.SeriesObj();
        ser2.setName("国五");
        ser2.setUnit("辆");
        ser2.setValues(new ArrayList<>());
        items.add(ser2);
        EChartsVO.SeriesObj ser3 = new EChartsVO.SeriesObj();
        ser3.setName("国四及以下");
        ser3.setUnit("辆");
        ser3.setValues(new ArrayList<>());
        items.add(ser3);
        List<String> list=new ArrayList<>();
        monitorsVo.forEach(item->{
            list.add(DateUtil.format(item.getEaTime(), DatePattern.NORM_DATE_PATTERN));
            items.get(0).getValues().add(item.getVideoEnterprise());
            items.get(1).getValues().add(item.getVideoNumber());
            items.get(2).getValues().add(item.getAccessControlEnterprise());
            items.get(3).getValues().add(item.getAccessControlNumber());
        });
        eChartsVO.setXData(list);
        eChartsVO.setSeries(items);
        return eChartsVO;
    }

    @Override
    public List<VideoMonitoringIssuesVo> videoMonitoringIssues() {
        String regionCode = SecurityUtils.getLoginUser().getSysUser().getRegionCode();

        List<String> regionCodes=new ArrayList<>();
        R<List<String>> r = baseRegionService.getRegionCodeListChild(regionCode);
        if(r.getCode()==200){
            regionCodes=r.getData();
        }
        return amVideoDevFiMapper.videoMonitoringIssues(regionCodes);
    }

    @Override
    public List<VideoMonitoringIssuesVo> otherEnterpriseMonitoringVideos() {
        String regionCode = SecurityUtils.getLoginUser().getSysUser().getRegionCode();

        List<String> regionCodes=new ArrayList<>();
        R<List<String>> r = baseRegionService.getRegionCodeListChild(regionCode);
        if(r.getCode()==200){
            regionCodes=r.getData();
        }
        return amVideoDevFiMapper.otherEnterpriseMonitoringVideos(regionCodes);
    }
}
