package com.skua.modules.controller;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

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.google.common.collect.Lists;
import com.skua.aop.annotation.CustomExceptionAnno;
import com.skua.core.api.vo.Result;
import com.skua.core.api.vo.TransTreeModel;
import com.skua.core.api.vo.TreeData;
import com.skua.core.aspect.annotation.AutoLog;
import com.skua.core.service.ISequenceService;
import com.skua.core.util.ConvertUtils;
import com.skua.core.util.TreeUtils;
import com.skua.modules.alarmtmp.entity.AlarmRuleAndRuleLevelConfig;
import com.skua.modules.alarmtmp.entity.AlarmRuleAndRuleLevelConfigBatch;
import com.skua.modules.alarmtmp.entity.AlarmRuleConfig;
import com.skua.modules.alarmtmp.entity.AlarmRuleLevelConfig;
import com.skua.modules.alarmtmp.entity.AlarmRuleLevelConfigTemplate;
import com.skua.modules.alarmtmp.service.AlarmRuleConfigService;
import com.skua.modules.alarmtmp.vo.AlarmPointPositionVO;
import com.skua.modules.alarmtmp.vo.AlarmRuleConfigBatchInfoVO;
import com.skua.modules.alarmtmp.vo.AlarmRuleConfigVO;
import com.skua.modules.system.datestandard.entity.SysMetricDict;
import com.skua.modules.system.datestandard.entity.SysMonitorMetricInfo;
import com.skua.modules.system.service.ISysDepartService;
import com.skua.modules.system.service.ISysFactoryInfoService;
import com.skua.modules.system.vo.SysDeptUserVO;
import com.skua.modules.system.vo.SysFactoryInfoNewVO;
import com.skua.tool.mpp.BaseFactory;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;


/**
 * @program: skboot
 * @description:
 * @author: xie chao
 * @create: 2020-11-02 09:34
 */
@Slf4j
@Api(tags = "报警配置")
@RestController
@RequestMapping("/alarm/config")
@AllArgsConstructor
public class AlarmRuleConfigController {

    private AlarmRuleConfigService alarmRuleConfigService;

    private ISysDepartService sysDepartService;

    private ISysFactoryInfoService sysFactoryInfoService;
    private ISequenceService sequenceService;

    /**
     * 新增警告信息
     *
     * @param alarmRuleAndRuleLevelConfig 需要添加的警告信息
     * @return
     */
    @AutoLog(value = "报警配置-添加")
    @ApiOperation(value = "报警配置-添加", notes = "报警配置-添加")
    @PostMapping(value = "/add")
    public Result<AlarmRuleConfig> addAlarmInfo(@RequestBody AlarmRuleAndRuleLevelConfig alarmRuleAndRuleLevelConfig) {

        Result<AlarmRuleConfig> result = new Result<>();

        try {
            //将对象保存到数据库中
            alarmRuleConfigService.saveAlarmRuleAndRuleLevelConfig(alarmRuleAndRuleLevelConfig);

            result.success("新增成功");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            result.error500("新增失败");
        }

        return result;
    }


    /**
     * 通过id删除报警信息
     *
     * @param id
     * @return
     */
    @AutoLog(value = "报警配置-通过id删除")
    @ApiOperation(value = "报警配置-通过id删除", notes = "报警配置-通过id删除")
    @DeleteMapping(value = "/delete")
    public Result<?> deleteAlarmInfo(@RequestParam(name = "id", required = true) String id) {

        Result<AlarmRuleConfig> result = new Result<>();

        try {
            //通过id查询数据
            AlarmRuleConfig alarmRuleConfigEntity = alarmRuleConfigService.getById(id);
            //判断对象是否存在
            if (alarmRuleConfigEntity == null) {
                result.error500("数据已删除");
            } else {
                //将isDelete的字段设置为1,表示数据已删除
                alarmRuleConfigEntity.setDelFlag(0);
                alarmRuleConfigService.updateById(alarmRuleConfigEntity);
            }
            result.success("删除成功");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            result.error500("删除失败");
        }

        return result;
    }

    /**
     * 通过id删除报警信息
     *
     * @param
     * @return
     */
    @AutoLog(value = "报警配置-判断是否已经存在该指标级别")
    @ApiOperation(value = "报警配置-判断是否已经存在该指标级别", notes = "报警配置-判断是否已经存在该指标级别")
    @GetMapping(value = "/checkLevel")
    public Result<String> checkLevel(String batchId, String alarmRuleLevelName, String alarmProgramCode, String departId, String alarmRuleType) {

        Result<String> result = new Result<>();

        try {
            if (StringUtils.isBlank(alarmRuleLevelName) || StringUtils.isBlank(alarmProgramCode) || StringUtils.isBlank(departId) || StringUtils.isBlank(alarmRuleType)) {
                result.setSuccess(true);
                return result;
            }
            String data = alarmRuleConfigService.checkLevel(batchId, alarmProgramCode, alarmRuleLevelName, departId, alarmRuleType);
            if (StringUtils.isNotBlank(data)) {
                result.setSuccess(false);
                result.setMessage(data);
            } else {
                result.setSuccess(true);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            result.error500("删除失败");
        }

        return result;
    }

    /**
     * 批量删除报警信息
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "报警配置-批量删除")
    @ApiOperation(value = "报警配置-批量删除", notes = "报警配置-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<AlarmRuleConfig> deleteBatchAlarmInfo(@RequestParam(name = "ids", required = true) String ids) {

        Result<AlarmRuleConfig> result = new Result<>();
        //判断参数是否有效
        if (ids == null || "".equals(ids.trim())) {
            result.error500("参数不识别");
        }

        try {
            //设置查询条件
            QueryWrapper<AlarmRuleConfig> queryWrapper = new QueryWrapper<>();
            queryWrapper.in("id", Arrays.asList(ids.split(",")));
            //根据ID查询所有符合条件的数据
            List<AlarmRuleConfig> alarmRuleConfigList = alarmRuleConfigService.list(queryWrapper);

            //将所有的对象的isDelete字段设置为0,表示数据已删除
            alarmRuleConfigList.forEach(obj -> obj.setDelFlag(0));

            alarmRuleConfigService.updateBatchById(alarmRuleConfigList);
            result.success("删除成功");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            result.error500("删除失败");
        }

        return result;
    }


    /**
     * 编辑报警信息
     *
     * @param alarmRuleAndRuleLevelConfig
     * @return
     */
    @AutoLog(value = "报警配置-编辑")
    @ApiOperation(value = "报警配置-编辑", notes = "报警配置-编辑")
    @PutMapping(value = "/edit")
    public Result<AlarmRuleConfig> editAlarmInfo(@RequestBody AlarmRuleAndRuleLevelConfig alarmRuleAndRuleLevelConfig) {

        Result<AlarmRuleConfig> result = new Result<>();
        try {

            alarmRuleConfigService.editAlarmInfo(alarmRuleAndRuleLevelConfig);

            result.success("修改成功");
        } catch (Exception e) {
            log.error("修改失败", e.getMessage());
            result.error500("修改失败");
        }

        return result;
    }

    /**
     * 分页列表查询
     *
     * @param alarmRuleConfigVO
     * @param pageNo
     * @param pageSize
     * @return
     */
    @AutoLog(value = "报警配置-分页列表查询")
    @ApiOperation(value = "报警配置-分页列表查询", notes = "报警配置-分页列表查询")
    @GetMapping(value = "/list")
    public Result<IPage<AlarmRuleConfigVO>> queryPageList(AlarmRuleConfigVO alarmRuleConfigVO,
                                                          @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                          @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {

        Result<IPage<AlarmRuleConfigVO>> result = new Result<>();
        try {
            QueryWrapper<AlarmRuleConfigVO> queryWrapper = new QueryWrapper<>();
            if (alarmRuleConfigVO.getAlarmParamName() != null) {
                queryWrapper.like("arc.alarm_param_name", alarmRuleConfigVO.getAlarmParamName());
            }
            String alarmRuleType = alarmRuleConfigVO.getAlarmRuleType();
            if (StringUtils.isNotBlank(alarmRuleType)) {
                String[] split = alarmRuleType.split(",");
                queryWrapper.in("arc.alarm_rule_type", Lists.newArrayList(split));
            }

            //报警配置大类改为动态化
            List<String> types = Arrays.asList(alarmRuleConfigVO.getType().split(","));
            queryWrapper.in("arc.alarm_rule_type", types);
            queryWrapper.orderByAsc("arc.alarm_rule_type");
            queryWrapper.orderByAsc("arc.alarm_rule_name");
            if (alarmRuleConfigVO.getDepartId() != null) {
                queryWrapper.eq("arc.depart_id", alarmRuleConfigVO.getDepartId());
            } else {
/*                //没有搜索条件时查询有权限的厂
                String departIds = BaseContextHandler.getDeparts();
                alarmRuleConfigVO.setDepartId(departIds);*/
            }

            Page<AlarmRuleConfigVO> page = new Page<>(pageNo, pageSize);
            IPage<AlarmRuleConfigVO> pageList = alarmRuleConfigService.getPage(page, queryWrapper);
            result.setSuccess(true);
            result.setResult(pageList);

        } catch (Exception e) {
            e.printStackTrace();
            log.error("报警标准配置查询失败", e.getMessage());
            result.setSuccess(false);
            result.setResult(null);

        }
        return result;
    }

    /**
     * 查询批次的名称和批次id
     *
     * @return
     */
    @AutoLog(value = "查询批次的名称和批次id")
    @ApiOperation(value = "查询批次的名称和批次id", notes = "查询批次的名称和批次id")
    @GetMapping(value = "/queryBatchInfoList")
    public Result<List<AlarmRuleConfigBatchInfoVO>> queryBatchInfoList(String alarmRuleName) {
        Result<List<AlarmRuleConfigBatchInfoVO>> result = new Result<List<AlarmRuleConfigBatchInfoVO>>();
        List<AlarmRuleConfigBatchInfoVO> alarmRuleConfigBatchVO = alarmRuleConfigService.queryBatchInfoList(alarmRuleName);
        result.setResult(alarmRuleConfigBatchVO);
        result.setSuccess(true);
        return result;
    }

    /**
     * 根据批次id查询批次对应的信息
     *
     * @return
     */
    @AutoLog(value = "根据批次id查询批次对应的信息")
    @ApiOperation(value = "根据批次id查询批次对应的信息", notes = "根据批次id查询批次对应的信息")
    @GetMapping(value = "/queryBatchInfoByBatchId")
    public Result<AlarmRuleConfigBatchInfoVO> queryBatchInfoByBatchId(String batchId) {
        Result<AlarmRuleConfigBatchInfoVO> result = new Result<>();
        AlarmRuleConfigBatchInfoVO alarmRuleConfigBatchVO = alarmRuleConfigService.queryBatchInfoByBatchId(batchId);
        result.setResult(alarmRuleConfigBatchVO);
        result.setSuccess(true);
        return result;
    }

    /**
     * 批量修改该批次的下的所有规则
     *
     * @return
     */
    @AutoLog(value = "批量修改该批次的下的所有规则")
    @ApiOperation(value = "批量修改该批次的下的所有规则", notes = "批量修改该批次的下的所有规则")
    @PostMapping(value = "/batchUpdateInfo")
    public Result<AlarmRuleAndRuleLevelConfigBatch> batchUpdateInfo(@RequestBody AlarmRuleAndRuleLevelConfig alarmRuleAndRuleLevelConfig) {
        Result<AlarmRuleAndRuleLevelConfigBatch> result = new Result<AlarmRuleAndRuleLevelConfigBatch>();
        AlarmRuleConfig alarmRuleConfigBatchInfoVO = alarmRuleAndRuleLevelConfig.getAlarmRuleConfig();
        if (StringUtils.isBlank(alarmRuleConfigBatchInfoVO.getBatchId())) {
            return result.error500("缺少必要参数");
        }

        try {

            alarmRuleConfigService.batchUpdateInfo(alarmRuleAndRuleLevelConfig);
            result.setSuccess(true);
            result.setMessage("批量修改成功");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("批量修改失败", e.getMessage());
            result.error500("批量修改失败");
        }

        return result;
    }

    /***************************短信通知人配置开始**********************************/
    /**
     * 获取厂站短信通知配置人员列表
     *
     * @return
     */
    @AutoLog(value = "获取厂站短信通知配置人员列表")
    @ApiOperation(value = "获取厂站短信通知配置人员列表", notes = "获取厂站短信通知配置人员列表")
    @GetMapping(value = "/getAlarmUserList")
    public Result<IPage<SysFactoryInfoNewVO>> getAlarmUserList(String departId,
                                                               @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                               @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        Result<IPage<SysFactoryInfoNewVO>> result = new Result<>();
        Page<SysFactoryInfoNewVO> page = new Page<>(pageNo, pageSize);
        IPage<SysFactoryInfoNewVO> data = sysFactoryInfoService.getAlarmUserList(page, departId);
        result.setResult(data);
        result.setSuccess(true);
        return result;
    }

    /**
     * 修改厂站短信通知配置人员
     *
     * @return
     */
    @AutoLog(value = "修改厂站短信通知配置人员")
    @ApiOperation(value = "修改厂站短信通知配置人员", notes = "修改厂站短信通知配置人员")
    @PostMapping(value = "/exitAlarmUser")
    public Result exitAlarmUser(@RequestBody SysFactoryInfoNewVO sysFactoryInfoNewVO) {
        Result result = new Result<>();
        sysFactoryInfoService.exitAlarmUser(sysFactoryInfoNewVO);
        result.setMessage("修改成功");
        result.setSuccess(true);
        return result;
    }
    /***************************短信通知人配置结束**********************************/


    /**
     * 编辑
     *
     * @return
     */
    @AutoLog(value = "编辑修改不同级别对应的上下限")
    @ApiOperation(value = "编辑修改不同级别对应的上下限", notes = "编辑修改不同级别对应的上下限")
    @PostMapping(value = "/exitInfoById")
    public Result exitInfoById(@RequestBody AlarmRuleConfigVO alarmRuleConfigVO) {
        Result result = new Result<>();
        alarmRuleConfigService.exitInfoById(alarmRuleConfigVO);
        result.setMessage("修改成功");
        result.setSuccess(true);
        return result;
    }

    /**
     * 根据厂ID获取部门人员机构树
     *
     * @param departId
     * @return
     */
    @GetMapping(value = "/queryDeptUserTreeListByDepartId")
    public Result<List<TreeData>> queryDeptUserTreeListByDepartId(String departId) {
        List<SysDeptUserVO> list = sysDepartService.queryDeptUserTreeList(departId);
        //将业务数据转换为构造树所需的数据结构
        List<TransTreeModel> transTreeModels = list.stream().map(bo -> convertToTreeModelxt(bo)).collect(Collectors.toList());
        List<TreeData> treeList = TreeUtils.buildTreeByRootId(transTreeModels, "");
        Result<List<TreeData>> result = new Result<>();
        try {
            result.setResult(treeList);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return result;
    }

    /**
     * 将SysDeptUserVO对象数据填充到TransTreeModel中
     *
     * @param sysDeptUserVO
     * @return
     */
    private TransTreeModel convertToTreeModelxt(SysDeptUserVO sysDeptUserVO) {
        TransTreeModel transTreeModel = new TransTreeModel();
        transTreeModel.setId(sysDeptUserVO.getId());
        transTreeModel.setPid(sysDeptUserVO.getParentId());
        transTreeModel.setTitle(sysDeptUserVO.getTitle());
        Map<String, String> map = new HashMap<String, String>();
        map.put("nodeType", sysDeptUserVO.getNodeType());
        map.put("phone", sysDeptUserVO.getPhone());
        map.put("id", String.valueOf(sequenceService.nextId()));
        transTreeModel.setMap(map);
        return transTreeModel;
    }

    @GetMapping("/pointPositionPage")
    @CustomExceptionAnno(description = "点位选择-查询未选择的标签")
    public Result<Object> pointPositionPageCtrl(@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                @RequestParam(defaultValue = "") String departId,
                                                @RequestParam(defaultValue = "") String metricName) {
        Result<Object> result = new Result<>();
        // 过滤: 查询已经塞入的点位
        String excludeSql = BaseFactory.JOIN()
                .select("alarm_program_code as id")
                .from(AlarmRuleConfig.class)
                .where()
                .eq(StringUtils.isNotEmpty(departId), AlarmRuleConfig::getDepartId, departId)
                .isNotNull(true, "alarm_program_code")
                .printSql();
        IPage<Map<String, Object>> queryMapPage = BaseFactory.JOIN()
                .select(false, SysMonitorMetricInfo.class)
                .from(SysMonitorMetricInfo.class)
                .where()
                .eq(StringUtils.isNotEmpty(departId), SysMonitorMetricInfo::getDepartId, departId)
                .like(StringUtils.isNotEmpty(metricName), SysMonitorMetricInfo::getMetricName, metricName)
                .notInSql(true, "id", excludeSql)
                .eq(true, "metric_type", "0")
                .apply(true, "(metric_uid_tag is null or metric_uid_tag = '')")
                .queryForPage(new Page<>(pageNo, pageSize));
        result.setResult(queryMapPage);
        return result;
    }

    @PostMapping("/pointPositionAdd")
    @CustomExceptionAnno(description = "点位选择-塞入未选择的标签")
    public Result<Object> pointPositionAddCtrl(@RequestBody AlarmPointPositionVO alarmPointPositionVO) {
    	List<SysMonitorMetricInfo> sysMonitorMetricInfoList = alarmPointPositionVO.getSysMonitorMetricInfoList();
    	String tabPageType = alarmPointPositionVO.getType();
    	
        List<AlarmRuleAndRuleLevelConfig> alarmRuleAndRuleLevelConfigs = Lists.newArrayList();
        //同一批次ID
        String batchId = String.valueOf(sequenceService.nextId());
        for (SysMonitorMetricInfo sysMonitorMetricInfo: sysMonitorMetricInfoList) {
            AlarmRuleAndRuleLevelConfig alarmRuleAndRuleLevelConfig = new AlarmRuleAndRuleLevelConfig();
            alarmRuleAndRuleLevelConfigs.add(alarmRuleAndRuleLevelConfig);

            AlarmRuleConfig alarmRuleConfig = new AlarmRuleConfig();
            String departId = sysMonitorMetricInfo.getDepartId();
            alarmRuleConfig.setBatchId(batchId);
            alarmRuleConfig.setAlarmRuleName(sysMonitorMetricInfo.getMetricName() + "报警");
            alarmRuleConfig.setAlarmRuleType(tabPageType);
            alarmRuleConfig.setAlarmParamName(sysMonitorMetricInfo.getMetricName());
            alarmRuleConfig.setAlarmParamCode(sysMonitorMetricInfo.getMetricUidTag());
            alarmRuleConfig.setAlarmProgramCode(sysMonitorMetricInfo.getId());
            alarmRuleConfig.setAlarmParamUnit(sysMonitorMetricInfo.getMetricUnit());
            alarmRuleConfig.setAlarmDataOverStandardRate("");
            alarmRuleConfig.setAlarmRuleStatus("1");
            alarmRuleConfig.setDelFlag(0);
            alarmRuleConfig.setDepartId(departId);
            String id = UUID.nameUUIDFromBytes((alarmRuleConfig.getAlarmRuleName() + alarmRuleConfig.getAlarmRuleType() + alarmRuleConfig.getAlarmParamName() + alarmRuleConfig.getAlarmParamCode() + alarmRuleConfig.getAlarmProgramCode() + alarmRuleConfig.getAlarmParamUnit() + alarmRuleConfig.getDepartId()).getBytes()).toString().replaceAll("-", "");
            alarmRuleConfig.setId(id);
            alarmRuleAndRuleLevelConfig.setAlarmRuleConfig(alarmRuleConfig);


            //获取仪表报警规则
            List<AlarmRuleLevelConfigTemplate> templateList = alarmRuleConfigService.getAlarmRuleTemplateList(departId, tabPageType);
            //构造报警级别对象集合
            List<AlarmRuleLevelConfig> alarmRuleLevelConfigs = Lists.newArrayList();
            templateList.forEach(template -> {
                String alarmTemplateLevelName = template.getAlarmTemplateLevelName();
                AlarmRuleLevelConfig alarmRuleLevelConfig = new AlarmRuleLevelConfig();
                alarmRuleLevelConfig.setAlarmRuleId(id);
                alarmRuleLevelConfig.setAlarmRuleLevelName(alarmTemplateLevelName);
                alarmRuleLevelConfig.setIsSendSms(template.getIsSendSms());
                alarmRuleLevelConfig.setIsSendNotice(template.getIsSendNotice());
                alarmRuleLevelConfig.setSmsSendFrequency(template.getSmsSendFrequency());
                alarmRuleLevelConfig.setSmsAllowSendTime(template.getSmsAllowSendTime());
                alarmRuleLevelConfig.setDepartId(departId);
                alarmRuleLevelConfig.setConfigStatus(0);//默认未配置
                alarmRuleLevelConfig.setTemplateType(template.getAlarmTemplateType());
                alarmRuleLevelConfig.setSort(template.getSort());
                alarmRuleLevelConfig.setIsFlowWork(template.getIsFlowWork());
                alarmRuleLevelConfig.setAlarmWorkRecipient(template.getAlarmWorkRecipient());
                alarmRuleLevelConfigs.add(alarmRuleLevelConfig);
            });
            alarmRuleAndRuleLevelConfig.setAlarmRuleLevelConfig(alarmRuleLevelConfigs);
        }

        if (!alarmRuleAndRuleLevelConfigs.isEmpty()) {
            alarmRuleConfigService.saveAlarmRuleAndRuleLevelConfigBatch(alarmRuleAndRuleLevelConfigs);
        }
        return Result.ok();
    }
    
    /**
     * <pre>
     * 报警一键配置
     * </pre>
     * @param type
     * @param departId
     * @return
     * @author Li Yuanyuan, 2023年3月27日 上午9:36:36
     * @Description: TODO(这里描述这个方法的需求变更情况)
     */
    @AutoLog(value = "一键配仪表和设备报警")
    @ApiOperation(value = "一键配仪表和设备报警", notes = "一键配仪表和设备报警")
    @GetMapping(value = "/addAllAlarmConfigByType")
    public Result<String> addAllAlarmConfigByType(String type, String departId) {
        Result<String> result = new Result<>();
        alarmRuleConfigService.addAllAlarmConfigByType(type, departId);
        result.setMessage("一键配置成功");
        result.setSuccess(true);
        return result;
    }

}