package com.njcn.device.node.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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.db.constant.DbConstant;
import com.njcn.device.biz.enums.DeviceResponseEnum;
import com.njcn.device.node.mapper.NodeMapper;
import com.njcn.device.node.service.INodeService;
import com.njcn.device.pq.pojo.bo.excel.NodeExcel;
import com.njcn.device.pq.pojo.param.NodeParam;
import com.njcn.device.pq.pojo.po.Node;
import com.njcn.web.factory.PageFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author cdf
 * @since 2022-01-07
 */
@Service
public class NodeServiceImpl extends ServiceImpl<NodeMapper, Node> implements INodeService {


    @Override
    public boolean addNode(NodeParam nodeParam) {
        checkNode(nodeParam, false);
        Node node = new Node();
        BeanUtils.copyProperties(nodeParam, node);
        node.setState(DataStateEnum.ENABLE.getCode());
        this.save(node);
        return true;
    }

    @Override
    public boolean updateNode(NodeParam.NodeUpdateParam nodeParam) {
        checkNode(nodeParam, true);
        Node node = new Node();
        BeanUtils.copyProperties(nodeParam, node);
        this.updateById(node);
        return true;
    }

    @Override
    public boolean delNode(String id) {
        return this.removeById(id);
    }

    @Override
    public boolean updateNodeState(String id, Integer state) {
        Node node = new Node();
        node.setId(id);
        node.setState(state);
        return this.updateById(node);
    }


    @Override
    public Page<Node> nodeList(NodeParam.NodeQueryParam nodeQueryParam) {
        QueryWrapper<Node> queryWrapper = new QueryWrapper<>();
        //查询参数不为空，进行条件填充
        if (Objects.nonNull(nodeQueryParam)) {
            if(Objects.nonNull(nodeQueryParam.getNodeGrade()) ){
                queryWrapper.eq("pq_node.node_grade",nodeQueryParam.getNodeGrade());
            }
            if(Objects.nonNull(nodeQueryParam.getSearchState()) ){
                queryWrapper.eq("pq_node.state",nodeQueryParam.getSearchState());
            }
            //模糊值查询
            if (StrUtil.isNotBlank(nodeQueryParam.getSearchValue())) {
                //仅提供名称、ip模糊查询
                queryWrapper.and(param -> param.like("pq_node.name", nodeQueryParam.getSearchValue())
                        .or().like("pq_node.ip", nodeQueryParam.getSearchValue()));
            }
            //排序字段不为空
            if (ObjectUtil.isAllNotEmpty(nodeQueryParam.getSortBy(), nodeQueryParam.getOrderBy())) {
                queryWrapper.orderBy(true, nodeQueryParam.getOrderBy().equals(DbConstant.ASC), StrUtil.toUnderlineCase(nodeQueryParam.getSortBy()));
            } else {
                //没有排序参数，默认根据sort字段排序，没有排序字段的，根据updateTime更新时间排序
                queryWrapper.orderBy(true, true, "pq_node.sort");
            }
        }
        return this.page(new Page<>(PageFactory.getPageNum(nodeQueryParam), PageFactory.getPageSize(nodeQueryParam)), queryWrapper);
    }

    @Override
    public  List<Node> nodeAllList(){
        LambdaQueryWrapper<Node> nodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        nodeLambdaQueryWrapper.eq(Node::getState,DataStateEnum.ENABLE.getCode()).orderByAsc(Node::getState);
        return this.list(nodeLambdaQueryWrapper);
    }
    @Override
    public Node getNodeById(String id) {
        return this.getById(id);
    }

    /**
     * 批量导入前置信息，如果库中已经存在的name，暂时忽略，后期可以考虑将重复的收集后，浏览器下载
     *
     * @param nodeExcels 前置信息
     */
    @Override
    public void saveBatchNodeInfo(List<NodeExcel> nodeExcels) {
        List<Node> nodeList = new ArrayList<>();
        if (!CollectionUtil.isEmpty(nodeExcels)) {
            for (NodeExcel nodeExcel : nodeExcels) {
                Node node = new Node();
                BeanUtils.copyProperties(nodeExcel, node);
                if (checkNodeWithResult(node)) {
                    //不存在重复的就加入到集合中，稍后进行批量插入
                    node.setState(DataStateEnum.ENABLE.getCode());
                    if (Objects.isNull(node.getNodeDevNum())) {
                        node.setNodeDevNum(300);
                    }
                    nodeList.add(node);
                }
            }
        }
        //批量插入
        if (CollectionUtil.isNotEmpty(nodeList)) {
            this.saveBatch(nodeList);
        }
    }

    @Override
    public Node getNodeByNodeName(String nodeName) {
        LambdaQueryWrapper<Node> nodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        nodeLambdaQueryWrapper.eq(Node::getName, nodeName)
                .eq(Node::getState, DataStateEnum.ENABLE.getCode());
        return this.baseMapper.selectOne(nodeLambdaQueryWrapper);
    }

    /**
     * 校验参数，检查是否存在相同编码的字典类型
     */
    private void checkNode(NodeParam nodeParam, boolean isExcludeSelf) {
        LambdaQueryWrapper<Node> nodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        nodeLambdaQueryWrapper
                .eq(Node::getName, nodeParam.getName())
                .eq(Node::getState, DataStateEnum.ENABLE.getCode());
        //更新的时候，需排除当前记录
        if (isExcludeSelf) {
            if (nodeParam instanceof NodeParam.NodeUpdateParam) {
                nodeLambdaQueryWrapper.ne(Node::getId, ((NodeParam.NodeUpdateParam) nodeParam).getId());
            }
        }
        int countByAccount = this.count(nodeLambdaQueryWrapper);
        //大于等于1个则表示重复
        if (countByAccount >= 1) {
            throw new BusinessException(DeviceResponseEnum.NODE_SAME_NAME);
        }
    }

    /**
     * 校验参数，检查是否存在相同编码的字典类型
     */
    private boolean checkNodeWithResult(Node node) {
        LambdaQueryWrapper<Node> nodeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        nodeLambdaQueryWrapper
                .eq(Node::getName, node.getName())
                .eq(Node::getState, DataStateEnum.ENABLE.getCode());
        int countByAccount = this.count(nodeLambdaQueryWrapper);
        //大于等于1个则表示重复
        if (countByAccount >= 1) {
            return false;
        }
        return true;
    }
}
