package cn.cecep.talroad.controller.app;

import cn.cecep.talroad.common.core.web.controller.BaseController;
import cn.cecep.talroad.common.core.web.domain.AjaxResults;
import cn.cecep.talroad.common.redis.service.RedisService;
import cn.cecep.talroad.common.security.utils.SecurityUtils;
import cn.cecep.talroad.controller.SMainDynamicControlController;
import cn.cecep.talroad.domain.*;
import cn.cecep.talroad.feign.BaseRegionService;
import cn.cecep.talroad.mapper.PcFactoryMapper;
import cn.cecep.talroad.service.*;
import cn.cecep.talroad.vo.EChartsVO;
import cn.cecep.talroad.vo.PcFactoryVo;
import cn.cecep.talroad.vo.PermitRequirementVo;
import cn.cecep.talroad.vo.SMainDynamicControlParamVo;
import cn.cecep.talroad.vo.query.*;
import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
import com.alibaba.nacos.shaded.com.google.common.collect.Maps;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: weizhuang
 * @Date:2023/2/22 9:32
 * @Version 1.0
 */
@Api(tags = "APP-特征码扫描")
@RestController
@RequestMapping("/app/signature")
public class SignatureController extends BaseController {

    @Autowired
    private RedisService redisService;

    @Autowired
    private IBMainPollDisService ibMainPollDisService;

    @Autowired
    private IBMainPollDisEnforcementService ibMainPollDisEnforcementService;

    @Autowired
    private IBMainPollDisEmlRecordService ibMainPollDisEmlRecordService;

    @Autowired
    private IBMainPollDisInformationService ibMainPollDisInformationService;

    @Autowired
    private IBMainPollDisNoiseRequireService ibMainPollDisNoiseRequireService;

    @Autowired
    private IBMainPollDisNoiseRegulationService ibMainPollDisNoiseRegulationService;

    @Autowired
    private IBMainPollDisGasMoutService ibMainPollDisGasMoutService;

    @Autowired
    private IBMainPollDisGasOoutService ibMainPollDisGasOoutService;

    @Autowired
    private IBMainPollDisGasToutService ibMainPollDisGasToutService;

    @Autowired
    private IBMainPollDisWaterToutService ibMainPollDisWaterToutService;

    @Autowired
    private IBMainMobileEnforcementService ibMainMobileEnforcementService;

    @Autowired
    private IPcFactoryService pcFactoryService;

    @Autowired
    private IPcOutletService pcOutletService;

    @Autowired
    private IPcControlRequirementsService pcControlRequirementsService;

    @Autowired
    private SMainDynamicControlController dynamicControlController;

    @Autowired
    private ISMainDynamicControlParamService sMainDynamicControlParamService;

    @Autowired
    private PcFactoryMapper factoryMapper;

    @Autowired
    private BMainPollDisGasPollService bMainPollDisGasPollService;
    @Autowired
    @Qualifier("baseRegionService")
    private BaseRegionService baseRegionService;

    @ApiOperation(value = "排污许可证-列表")
    @GetMapping("/pullXkzList/{factoryId}")
    public AjaxResults<List<BMainPollDis>> pullXkzList(@PathVariable("factoryId") String factoryId) {
        return AjaxResults.success(ibMainPollDisService.pullXkzList(factoryId));
    }

    @ApiOperation(value = "排污许可证-执行报告要求")
    @GetMapping("/pullImplementReport/{xkzId}")
    public AjaxResults<List<BMainPollDisEnforcement>> pullImplementReport(@PathVariable("xkzId") String xkzId) {
        return AjaxResults.success(ibMainPollDisEnforcementService.pullImplementReport(xkzId));
    }

    @ApiOperation(value = "排污许可证-台账记录要求")
    @GetMapping("/pullBookRecord/{xkzId}")
    public AjaxResults<List<BMainPollDisEmlRecord>> pullBookRecord(@PathVariable("xkzId") String xkzId) {
        return AjaxResults.success(ibMainPollDisEmlRecordService.pullBookRecord(xkzId));
    }

    @ApiOperation(value = "排污许可证-信息公开要求")
    @GetMapping("/pullInformationDisclosure/{xkzId}")
    public AjaxResults<BMainPollDisInformation> pullInformationDisclosure(@PathVariable("xkzId") String xkzId) {
        return AjaxResults.success(ibMainPollDisInformationService.pullInformationDisclosure(xkzId));
    }

    @ApiOperation(value = "排污许可证-其他许可要求-管理要求")
    @GetMapping("/pullOtherXkAsk/manage/{xkzId}")
    public AjaxResults<BMainPollDisNoiseRequire> pullOtherXkAskManage(@PathVariable("xkzId") String xkzId) {
        return AjaxResults.success(ibMainPollDisNoiseRequireService.pullOtherXkAskManage(xkzId));
    }

    @ApiOperation(value = "排污许可证-其他许可要求-整改规定列表")
    @GetMapping("/pullOtherXkAsk/rectifyAndReform/{xkzId}")
    public AjaxResults<List<BMainPollDisNoiseRegulation>> pullOtherXkAskRectifyAndReform(@PathVariable("xkzId") String xkzId) {
        return AjaxResults.success(ibMainPollDisNoiseRegulationService.pullOtherXkAskRectifyAndReform(xkzId));
    }

    @ApiOperation(value = "排污许可证-许可量要求")
    @GetMapping("/pullPermitRequirement/{xkzId}")
    public AjaxResults<Map<Object, Object>> pullPermitRequirement(@PathVariable("xkzId") String xkzId) {
        List<PermitRequirementVo> res = Lists.newArrayList();
        BMainPollDisGasToutQuery moutQuery = new BMainPollDisGasToutQuery();
        moutQuery.setPollDisId(xkzId);
        moutQuery.setPageNum(1);
        moutQuery.setPageSize(1000);
        IPage<BMainPollDisGasPoll> bMainPollDisGasPollIPage = bMainPollDisGasPollService.pullPage(moutQuery);
        if (bMainPollDisGasPollIPage != null && !CollectionUtils.isEmpty(bMainPollDisGasPollIPage.getRecords())) {
            res.addAll(bMainPollDisGasPollIPage.getRecords().stream().map(p -> {
                PermitRequirementVo yzzVo = new PermitRequirementVo();
                yzzVo.setPollutantsType(p.getPollutantsType());
                yzzVo.setPollutantsTotalFrist(p.getPollutantsTotalYzzFrist());
                yzzVo.setPollutantsTotalSecond(p.getPollutantsTotalYzzSecond());
                yzzVo.setPollutantsTotalThird(p.getPollutantsTotalYzzThird());
                yzzVo.setPollutantsTotalFourth(p.getPollutantsTotalYzzFourth());
                yzzVo.setPollutantsTotalFifth(p.getPollutantsTotalYzzFifth());
                yzzVo.setVent("废气有组织");
                return yzzVo;
            }).collect(Collectors.toList()));
            res.addAll(bMainPollDisGasPollIPage.getRecords().stream().map(p -> {
                PermitRequirementVo wzzVo = new PermitRequirementVo();
                wzzVo.setPollutantsType(p.getPollutantsType());
                wzzVo.setPollutantsTotalFrist(p.getPollutantsTotalWzzFrist());
                wzzVo.setPollutantsTotalSecond(p.getPollutantsTotalWzzSecond());
                wzzVo.setPollutantsTotalThird(p.getPollutantsTotalWzzThird());
                wzzVo.setPollutantsTotalFourth(p.getPollutantsTotalWzzFourth());
                wzzVo.setPollutantsTotalFifth(p.getPollutantsTotalWzzFifth());
                wzzVo.setVent("废气无组织");
                return wzzVo;
            }).collect(Collectors.toList()));
            res.addAll(bMainPollDisGasPollIPage.getRecords().stream().map(p -> {
                PermitRequirementVo vo = new PermitRequirementVo();
                vo.setPollutantsType(p.getPollutantsType());
                vo.setPollutantsTotalFrist(p.getPollutantsTotalFrist());
                vo.setPollutantsTotalSecond(p.getPollutantsTotalSecond());
                vo.setPollutantsTotalThird(p.getPollutantsTotalThird());
                vo.setPollutantsTotalFourth(p.getPollutantsTotalFourth());
                vo.setPollutantsTotalFifth(p.getPollutantsTotalFifth());
                vo.setVent("废气全厂合计");
                return vo;
            }).collect(Collectors.toList()));
        }

        BMainPollDisWaterToutQuery wtoutQuery = new BMainPollDisWaterToutQuery();
        wtoutQuery.setPollDisId(xkzId);
        wtoutQuery.setPageNum(1);
        wtoutQuery.setPageSize(1000);
        IPage<BMainPollDisWaterTout> bMainPollDisWaterToutIPage = ibMainPollDisWaterToutService.pullPage(wtoutQuery);
        if (bMainPollDisWaterToutIPage != null && !CollectionUtils.isEmpty(bMainPollDisWaterToutIPage.getRecords())) {
            res.addAll(bMainPollDisWaterToutIPage.getRecords().stream().map(p -> {
                PermitRequirementVo vo = new PermitRequirementVo();
                BeanUtils.copyProperties(p, vo);
                vo.setVent("废水全场合计");
                return vo;
            }).collect(Collectors.toList()));
        }

        Map<Object, Object> resMaps = Maps.newHashMap();
        resMaps.put("table", res);
        BMainPollDis query = new BMainPollDis();
        query.setDataId(xkzId);
        List<BMainPollDis> bMainPollDis = ibMainPollDisService.selectBMainPollDisList(query);
        resMaps.put("pollDisLicenseDeadline", CollectionUtils.isEmpty(bMainPollDis) ? "" : bMainPollDis.get(0).getPollDisLicenseDeadline());// 许可证有效期
        return AjaxResults.success(resMaps);
    }

    @ApiOperation(value = "排污许可证-执法监察")
    @GetMapping("/pullLawSupervise/{factoryId}/{startTime}/{endTime}")
    public AjaxResults<Map<Object, Object>> pullLawSupervise(@PathVariable("factoryId") String factoryId,
                                                             @PathVariable("startTime") String startTime,
                                                             @PathVariable("endTime") String endTime) {

        Map<Object, Object> res = Maps.newHashMap();
        BMainMobileEnforcementQuery query = new BMainMobileEnforcementQuery();
        query.setFactoryId(factoryId);
        query.setEnforcementStartTime(startTime + "-01 00:00:00");
        query.setEnforcementEndTime(endTime + "-31 23:59:59");
        query.setPageSize(1000);
        query.setPageNum(1);
        IPage<BMainMobileEnforcement> bMainMobileEnforcementIPage = ibMainMobileEnforcementService.pullPage(query);
        if (bMainMobileEnforcementIPage == null || CollectionUtils.isEmpty(bMainMobileEnforcementIPage.getRecords())) {
            res.put("pieChart", Lists.newArrayList());
            res.put("table", Lists.newArrayList());
        } else {
            Map<String, List<BMainMobileEnforcement>> collect = bMainMobileEnforcementIPage.getRecords().stream().collect(Collectors.groupingBy(BMainMobileEnforcement::getTaskType));
            List<Map<Object, Object>> maps = Lists.newArrayList();
            collect.forEach((k, v) -> {
                Map<Object, Object> map = Maps.newHashMap();
                map.put("name", k);
                map.put("value", v.size());
                maps.add(map);
            });
            res.put("pieChart", maps);
            res.put("table", bMainMobileEnforcementIPage.getRecords());
        }
        PcFactory pcFactory = factoryMapper.selectById(factoryId);
        res.put("name", pcFactory == null ? "" : pcFactory.getFactoryName());
        return AjaxResults.success(res);
    }

    @ApiOperation(value = "获取企业基本信息详细信息")
    @GetMapping(value = "/pcFactory/{id}")
    public AjaxResults<PcFactoryVo> getFactoryInfo(@PathVariable("id") String id) {
        return AjaxResults.success(pcFactoryService.getInfo(id));
    }

    @ApiOperation(value = "查询废气有组织、无组织排口")
    @GetMapping("/pcOutlet/list")
    public AjaxResults<IPage<PcOutlet>> list(PcOutletAppQuery pcOutlet) {
        Page<PcOutlet> page = new Page<>(pcOutlet.getPageNum(), pcOutlet.getPageSize());
        IPage<PcOutlet> list = pcOutletService.page(page, PcOutletAppQuery.createLambdaQueryWrapper(pcOutlet));
        return AjaxResults.success(list);
    }

    @ApiOperation(value = "查询企业废气排口，按照排口分类（有组织、无组织）分组返回")
    @GetMapping("/pcOutlet/gas/groupByType")
    public AjaxResults<Map<String, List<PcOutlet>>> getGasOutletGroupByType(String factoryId, String outletName) {
        List<PcOutlet> list = pcOutletService.list(new QueryWrapper<PcOutlet>()
                .eq("factory_id", factoryId)
                .and(StringUtils.isNotEmpty(outletName), wrapper -> {
                    wrapper.like("outlet_name", outletName).or().like("outlet_code", outletName);
                })
                .eq("pollutant_type", "1")
                .orderByAsc("outlet_code", "id")
        );
        Map<String, List<PcOutlet>> data = list.stream().collect(Collectors.groupingBy(PcOutlet::getPollutantOutletType));
        return AjaxResults.success(data);
    }

    @ApiOperation(value = "获取废气有组织、无组织排口详细信息")
    @GetMapping(value = "/pcOutlet/{id}")
    public AjaxResults<PcOutlet> getOutletInfo(@PathVariable("id") String id) {
        return AjaxResults.success(pcOutletService.getInfo(id));
    }

    @ApiOperation(value = "查询管控要求")
    @GetMapping("/pcControlRequirements/list")
    public AjaxResults<IPage<PcControlRequirements>> list(PcControlRequirementsQuery pcControlRequirements) {
        Page<PcControlRequirements> page = new Page<>(pcControlRequirements.getPageNum(), pcControlRequirements.getPageSize());
        IPage<PcControlRequirements> list = pcControlRequirementsService.page(page, PcControlRequirementsQuery.createLambdaQueryWrapper(pcControlRequirements));
        return AjaxResults.success(list);
    }

    @ApiOperation(value = "查询基本信息-废气、废水排口档案-动态管控信息")
    @GetMapping("/smainDynamicControl/list")
    public AjaxResults<IPage<SMainDynamicControl>> list(SMainDynamicControlQuery sMainDynamicControl)
    {
        return dynamicControlController.list(sMainDynamicControl);
    }

    @ApiOperation(value = "获取动态管控信息参数表格数据")
    @GetMapping("/smainDynamicControlParam/paramTableData")
    public AjaxResults<SMainDynamicControlParamVo.Table> list(String factoryId, String outletId, String controlTypeCode) {
        SMainDynamicControlParamVo.Table data = sMainDynamicControlParamService.getParamTableData(factoryId, outletId, controlTypeCode);
        return AjaxResults.success(data);
    }

    @Autowired
    private ISEnvGasMonRealService sEnvGasMonRealService;

    @Autowired
    private ISEnvGasRealService sEnvGasRealService;

    @Autowired
    private ISEnvWaterMonRealService sEnvWaterMonRealService;

    @Autowired
    private ISupermonitorDrainOutletService supermonitorDrainOutletService;

    @ApiOperation(value = "查询废气监测曲线图数据")
    @GetMapping("/sEnvGasMonReal/charData")
    public AjaxResults<EChartsVO> getCharData(SEnvGasMonRealQuery sEnvGasMonReal) {
        EChartsVO charData = sEnvGasMonRealService.getCharData(sEnvGasMonReal);
        return AjaxResults.success(charData);
    }

    @ApiOperation(value = "查询无组织监控曲线图数据")
    @GetMapping("/sEnvGasReal/charData")
    public AjaxResults<EChartsVO> getCharData(SEnvGasRealQuery sEnvGasReal) {
        EChartsVO charData = sEnvGasRealService.getCharData(sEnvGasReal);
        return AjaxResults.success(charData);
    }

    @ApiOperation(value = "查询废水监测曲线图数据")
    @GetMapping("/sEnvWaterMonReal/charData")
    public AjaxResults<EChartsVO> charData(SEnvWaterMonRealQuery sEnvWaterMonReal) {
        EChartsVO chartsVO = sEnvWaterMonRealService.getCharData(sEnvWaterMonReal);
        return AjaxResults.success(chartsVO);
    }

    @ApiOperation(value = "查询排污口")
    @GetMapping("/supermonitorDrainOutlet/list")
    public AjaxResults<IPage<SupermonitorDrainOutlet>> list(SupermonitorDrainOutletQuery supermonitorDrainOutlet) {
        Page<SupermonitorDrainOutlet> page = new Page<>(supermonitorDrainOutlet.getPageNum(), supermonitorDrainOutlet.getPageSize());
        IPage<SupermonitorDrainOutlet> list = supermonitorDrainOutletService.page(page, SupermonitorDrainOutletQuery.createLambdaQueryWrapper(supermonitorDrainOutlet));
        return AjaxResults.success(list);
    }

    /**
     * 查询全部企业点位时，一次性返回大量数据，响应时间太长，分批返回
     */
    private void setPageRecords(PcFactoryQuery.SearchVo searchVo, Page<PcFactoryVo.MapPointVo> page) {
        if (searchVo.getPageNum() != null && searchVo.getPageNum() == 1) {
            // searchVo.getPageNum() = 1 返回前2000条
            page.setRecords(page.getRecords().stream().skip(0).limit(2000).collect(Collectors.toList()));
        } else if (searchVo.getPageNum() != null && searchVo.getPageNum() == 2) {
            // searchVo.getPageNum() = 2 返回2001-7000条
            page.setRecords(page.getRecords().stream().skip(2000).limit(5000).collect(Collectors.toList()));
        } else if (searchVo.getPageNum() != null && searchVo.getPageNum() == 3) {
            // searchVo.getPageNum() = 3 返回7001以后的
            page.setRecords(page.getRecords().stream().skip(7000).collect(Collectors.toList()));
        }
    }

    @ApiOperation(value = "企业高级搜索，只返回地图点位数据")
    @PostMapping("/search")
    public AjaxResults<IPage<PcFactoryVo.MapPointVo>> search(@RequestBody PcFactoryQuery.SearchVo searchVo) {
        String regionCode = SecurityUtils.getLoginUser().getSysUser().getRegionCode();

        // 查询条件是否为空
        boolean emptyParams = searchVo.getLabelMap().size() == 0 && StringUtils.isEmpty(searchVo.getFactoryName());

        //判断 只有查询全部企业信息时，存在，直接返回
        if (emptyParams) {
            if (redisService.hasKey("MapPcFactoryALlInfo"+regionCode)) {
                Page<PcFactoryVo.MapPointVo> page = redisService.getCacheObject("MapPcFactoryALlInfo"+regionCode);
                setPageRecords(searchVo, page);
                return AjaxResults.success(page);
            }
        }
        Page<PcFactoryVo.MapPointVo> page = new Page<>(searchVo.getPageNum(), searchVo.getPageSize());

        List<PcFactoryVo> search = pcFactoryService.search(null, searchVo, "home",regionCode);

        List<PcFactoryVo.MapPointVo> collect = search.stream().map(o -> {
            PcFactoryVo.MapPointVo vo = new PcFactoryVo.MapPointVo();
            BeanUtils.copyProperties(o, vo);
            return vo;
        }).collect(Collectors.toList());
        page.setRecords(collect);
        page.setTotal(collect.size());

        //判断 只有查询全部企业信息时，才进行缓存
        if (emptyParams) {
            //判断 key不存在时，进行缓存
            if (!redisService.hasKey("MapPcFactoryALlInfo"+regionCode)) {
                redisService.setCacheObject("MapPcFactoryALlInfo"+regionCode, page);
            }
            setPageRecords(searchVo, page);
        }
        return AjaxResults.success(page);
    }

}
