package com.dsk.monitor.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dsk.common.core.domain.R;
import com.dsk.common.core.page.TableDataInfo;
import com.dsk.common.helper.LoginHelper;
import com.dsk.common.utils.redis.RedisUtils;
import com.dsk.cscec.mapper.DCustomerMapper;
import com.dsk.monitor.domain.dto.PushMonitorRules;
import com.dsk.monitor.domain.vo.*;
import com.dsk.monitor.mapper.PushMonitorInfoMapper;
import com.dsk.monitor.mapper.PushMonitorRulesMapper;
import com.dsk.monitor.service.MonitorService;
import com.dsk.search.service.BusinessOpportunityRadarService;
import com.dsk.system.utils.DskOpenApiUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.time.Duration;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName MonitorServiceImpl
 * @Description
 * @Author Dgm
 * @Date 2023/12/9 10:04
 * @Version
 */
@Slf4j
@Service
public class MonitorServiceImpl implements MonitorService {

    @Resource
    private PushMonitorInfoMapper monitorInfoMapper;

    @Resource
    private PushMonitorRulesMapper rulesMapper;

    @Resource
    private DCustomerMapper customerMapper;

    @Autowired
    private BusinessOpportunityRadarService opportunityRadarService;

    @Resource
    private DskOpenApiUtil dskOpenApiUtil;

    @Override
    public R insert(PushMonitorInfoVo pushMonitorInfoDto) {
        monitorInfoMapper.insert(pushMonitorInfoDto);
        return R.ok();
    }

    @Override
    public R rulesSelect(PushMonitorRulesSelectVo addVo) {
        Long userId = LoginHelper.getUserId();
        if (ObjectUtil.isNotEmpty(userId)) {
            addVo.setUserId(userId);
        }
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/monitor/company/supplier/system/queryDimensionEnum", BeanUtil.beanToMap(addVo, false, false));
        return BeanUtil.toBean(map, R.class);
    }

    @Override
    public R insertRules(PushMonitorRulesVo monitorRulesDto) {
        Long userId = LoginHelper.getUserId();
        if (ObjectUtil.isNotEmpty(userId)) {
            monitorRulesDto.setUserId(userId);
        }
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_id", monitorRulesDto.getUserId());
        PushMonitorRules detail = rulesMapper.selectOne(queryWrapper);
        if (ObjectUtil.isEmpty(detail)) {
            rulesMapper.insert(monitorRulesDto);
        } else {
            monitorRulesDto.setId(detail.getId());
            rulesMapper.updateById(monitorRulesDto);
        }
        return R.ok();
    }

    @Override
    public R rulesDetail(PushMonitorRulesDetailVo detailVo) {
        Long userId = LoginHelper.getUserId();
        if (ObjectUtil.isNotEmpty(userId)) {
            detailVo.setUserId(userId);
        }
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_id", detailVo.getUserId());
        PushMonitorRules detail = rulesMapper.selectOne(queryWrapper);
        return R.ok(detail);
    }

    @Override
    public TableDataInfo companyDynamicPage(PushMonitorDynamicPageVo pageVo) throws Exception {
        Long userId = LoginHelper.getUserId();
        if (ObjectUtil.isNotEmpty(userId)) {
            pageVo.setUserId(userId);
            pageVo.getCondition().setUserId(userId);
        }
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/monitor/company/info/companyDynamicList", BeanUtil.beanToMap(pageVo, false, false));
        log.info("companyDynamicPage=============================>" + map);
        return dskOpenApiUtil.responsePageT(map);
    }

    @Override
    public Map<String, Object> companyDynamicPageScheduled(PushMonitorDynamicPageVo pageVo) throws Exception {
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/monitor/company/info/companyDynamicList", BeanUtil.beanToMap(pageVo, false, false));
        log.info("companyDynamicPage=============================>" + map);
        return map;
    }

    @Override
    public TableDataInfo reportPage(PushMonitorReportPageVo pageVo) throws Exception {
        Long userId = LoginHelper.getUserId();
        if (ObjectUtil.isNotEmpty(userId)) {
            pageVo.setUserId(userId);
            pageVo.getCondition().setUserId(userId);
        }
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/monitor/company/info/monitor/report", BeanUtil.beanToMap(pageVo, false, false));
        return dskOpenApiUtil.responsePage(map);
    }

    @Override
    public TableDataInfo companyPage(PushMonitorCompanyPageVo pageVo) throws Exception {
        Long userId = LoginHelper.getUserId();
        if (ObjectUtil.isNotEmpty(userId)) {
            pageVo.setUserId(userId);
            pageVo.getCondition().setUserId(userId);
        }
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/monitor/company/supplier/system/paging", BeanUtil.beanToMap(pageVo, false, false));
        return dskOpenApiUtil.responsePage(map);
    }

    @Override
    public TableDataInfo queryMonitorCompany(MonitorQueryMonitorCompanyPageVo pageVo) throws Exception {
        Long userId = LoginHelper.getUserId();
        if (ObjectUtil.isNotEmpty(userId)) {
            pageVo.setUserId(userId);
        }
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/monitor/company/supplier/system/queryCancelMonitorCompany", BeanUtil.beanToMap(pageVo, false, false));
        return dskOpenApiUtil.responsePage(map);
    }

    @Override
    public R systemAdd(PushMonitorCompanyAddVo addVo) {
        Long userId = LoginHelper.getUserId();
        if (ObjectUtil.isNotEmpty(userId)) {
            addVo.setUserId(userId);
        }
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/monitor/company/supplier/system/add", BeanUtil.beanToMap(addVo, false, false));
        return BeanUtil.toBean(map, R.class);
    }


    @Override
    public R systemCancel(PushMonitorCompanyCancelVo cancelVo) {
        Long userId = LoginHelper.getUserId();
        if (ObjectUtil.isNotEmpty(userId)) {
            cancelVo.setUserId(userId);
        }
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/monitor/company/supplier/system/cancel", BeanUtil.beanToMap(cancelVo, false, false));
        return BeanUtil.toBean(map, R.class);
    }

    @Override
    public R systemImport(MultipartFile file, PushMonitorCompanyImportAddVo importAddVo) {
        Long userId = LoginHelper.getUserId();
        if (ObjectUtil.isNotEmpty(userId)) {
            importAddVo.setUserId(userId);
        }
        //存放保单信息
        List<String> companyList = new ArrayList<String>();
        // 设置redisKey
        String lockKey = "stockKey" + userId;
        // 设置redisValue
        String value = UUID.randomUUID().toString();
        try {
            // 这里默认设置超时时间为30秒
            boolean hasKey = RedisUtils.setObjectIfAbsent(lockKey, value, Duration.ofMillis(1000 * 30));
            if (!hasKey) {
                return R.fail("数据正在上传请等待");
            }

            //如果文件不存在  则文件上传失败
            if (file == null) {
                return R.fail("操作失敗，数据异常，請使用正确的模板");
            }
            if (file.isEmpty()) {
                return R.fail("操作失敗，数据异常，請使用正确的模板");
            }

            //得到整个excel
            XSSFWorkbook wook = new XSSFWorkbook((file.getInputStream()));
            //得到第一个表单sheet
            Sheet sheet = wook.getSheetAt(0);
            //得到最后一行的行号
            int lastRowNum = sheet.getLastRowNum();
            //如果总行数小于等于2 （没有数据）提示数据异常
            if ((lastRowNum) < 1) {
                return R.fail("未提供有效数据，请确认！");
            }

            //进行excel格式判定
            String name = sheet.getRow(2).getCell(0) + "";
            //只要其中一个不满足则格式有误
            if (!"企业名称".equals(name)) {
                return R.fail("操作失败，数据异常，请使用正确的模板");
            }
            //行列皆从0开始
            for (int i = 3; i <= lastRowNum; i++) {
                String companyNameStr = "";
                // 统一社会信用代码
                Cell companyName = sheet.getRow(i).getCell(0);
                if (ObjectUtil.isNotEmpty(companyName)) {
                    String cn = companyName.toString();
                    companyNameStr = cn.trim();
                }
                companyList.add(companyNameStr);
            }
        } catch (Exception e) {
            log.error("", e.getMessage());
        } finally {
            RedisUtils.hasValueDelete(lockKey, value);
        }
        if (ObjectUtil.isEmpty(companyList)) {
            return R.fail("操作失败");
        }
        importAddVo.setNames(companyList);
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/monitor/company/supplier/system/addPatch", BeanUtil.beanToMap(importAddVo, false, false));
        log.info("systemImport==================================>" + map);
        return BeanUtil.toBean(map, R.class);

    }


    @Override
    public R systemDetail(PushMonitorSystemDetailVo cancelVo) {
        String dimensionName = cancelVo.getDimensionName();
        cancelVo = getDetailVo(cancelVo);
        Map<String, Object> map = new HashMap<>();
        switch (dimensionName) {
            case "新增经营异常":
                map = dskOpenApiUtil.requestBody("/operate/enterpriseCredit/abnormalDetail", BeanUtil.beanToMap(cancelVo, false, false));
                break;
            case "新增股权冻结":
                map = dskOpenApiUtil.requestBody("/operate/enterpriseCredit/judicialFreezesDetail", BeanUtil.beanToMap(cancelVo, false, false));
                break;
            case "新增被执行人":
                map = dskOpenApiUtil.requestBody("/operate/enterpriseCredit/executedPersonsDetail", BeanUtil.beanToMap(cancelVo, false, false));
                break;
            case "新增失信被执行人":
                map = dskOpenApiUtil.requestBody("/operate/enterpriseCredit/executedDetail", BeanUtil.beanToMap(cancelVo, false, false));
                break;
            case "新增法院公告":
                map = dskOpenApiUtil.requestBody("/operate/enterpriseCredit/noticesDetail", BeanUtil.beanToMap(cancelVo, false, false));
                break;
            case "新增裁判文书":
                map = dskOpenApiUtil.requestBody("/operate/enterpriseCredit/lawsuitsDetail", BeanUtil.beanToMap(cancelVo, false, false));
                break;
            case "新增开庭公告":
                map = dskOpenApiUtil.requestBody("/operate/enterpriseCredit/kaiTingDetail", BeanUtil.beanToMap(cancelVo, false, false));
                break;
            case "行政处罚":
                map = dskOpenApiUtil.requestBody("/operate/enterpriseCredit/penalizeDetail", BeanUtil.beanToMap(cancelVo, false, false));
                break;
            default:
                break;
        }
        return BeanUtil.toBean(map, R.class);
    }

    /***
     *@Description: 参数处理
     *@Param:
     *@return: com.dsk.monitor.domain.vo.PushMonitorSystemDetailVo
     *@Author: Dgm
     *@date: 2023/12/15 15:43
     */
    public PushMonitorSystemDetailVo getDetailVo(PushMonitorSystemDetailVo detailVo) {
        String value1 = null;
        String value2 = null;
        String sourceId = detailVo.getSourceId();
        String[] arr = sourceId.split("_");
        if (arr.length > 1) {
            value1 = (arr[0]);
            value2 = (arr[1]);
        }
        if (arr.length > 0) {
            value1 = (arr[0]);
        }
        String dimensionName = detailVo.getDimensionName();
        switch (dimensionName) {
            case "新增经营异常":
                detailVo = new PushMonitorSystemDetailVo(value1, null, null, value2);
                break;
            case "新增股权冻结":
                detailVo = new PushMonitorSystemDetailVo(value1, value2, null, null);
                break;
            case "新增被执行人":
                detailVo = new PushMonitorSystemDetailVo(value1, null, null, null);
                break;
            case "新增失信被执行人":
                detailVo = new PushMonitorSystemDetailVo(value1, null, null, null);
                break;
            case "新增法院公告":
                detailVo = new PushMonitorSystemDetailVo(value1, null, null, value2);
                break;
            case "新增裁判文书":
                detailVo = new PushMonitorSystemDetailVo(value1, null, null, value2);
                break;
            case "新增开庭公告":
                detailVo = new PushMonitorSystemDetailVo(value1, null, value2, null);
                break;
            case "行政处罚":
                detailVo = new PushMonitorSystemDetailVo(value1);
                break;
            default:
                break;
        }
        return detailVo;
    }

    @Override
    public Map<String, Object> settingHoliday(PushSettingHolidayVo holidayVo) throws Exception {
        Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/monitor/push/settingHoliday", BeanUtil.beanToMap(holidayVo, false, false));
        log.info("companyDynamicPage=============================>" + map);
        return map;
    }

    @Override
    public R addDefaultCompany() {
        //获取所有供应商企业名称
        List<Integer> idList = new ArrayList<>();

        //如果没有上一次的企业id数据则直接返回
        if (RedisUtils.hasKey("monitorCompanyList")){
            log.info("添加默认企业监控：企业id从缓存中取");
            idList = RedisUtils.getCacheList("monitorCompanyList");
        }else {
            List<String> list = customerMapper.allSearchCompanyNameList();
            for (String companyName : list) {
                //循环匹配 得到能关联上的企业id
                Map<String, Object> map = opportunityRadarService.enterpriseByName(companyName);
                if (!ObjectUtils.isEmpty(map.get("data"))) {
                    Map<String, Object> data = BeanUtil.beanToMap(map.get("data"));
                    Integer companyId = MapUtil.getInt(data, "jskEid");
                    idList.add(companyId);
                }
            }
            RedisUtils.setCacheList("monitorCompanyList",idList);
            //设置过期时间两天
            RedisUtils.expire("monitorCompanyList",172800);
        }
        //去除重复企业id
        idList = idList.stream().distinct().collect(Collectors.toList());
        log.info("获取供应商企业id数量："+idList.size());

        PushMonitorCompanyAddVo addVo = new PushMonitorCompanyAddVo();
        Long userId = LoginHelper.getUserId();
        if (ObjectUtil.isNotEmpty(userId)) {
            addVo.setUserId(userId);
        }
        addVo.setSystemCode("ZJYJ");
        int size = idList.size();
        if (size<=200){
            addVo.setCid(idList);
            log.info("中建一局用户添加默认监控企业！");
            Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/monitor/company/addDefaultCompany", BeanUtil.beanToMap(addVo, false, false));
        }else {
            //循环次数
            int num =  (size+(200-1))/200;
            for (int i = 0; i < num; i++) {
                List<Integer> newList = new ArrayList<>();
                if (((i+1)*200)>=size){
                    //如果下标索引大于 list容量
                    newList = idList.subList(i*200, size);
                }else {
                    newList = idList.subList(i*200, (i+1)*200);
                }
                addVo.setCid(newList);
                log.info("中建一局用户添加默认监控企业------->循环添加："+i*200+"----"+(i+1)*200);
                Map<String, Object> map = dskOpenApiUtil.requestBody("/operate/monitor/company/addDefaultCompany", BeanUtil.beanToMap(addVo, false, false));
            }
        }
        return R.ok("默认企业添加中，请稍候");
    }
}
