package com.njcn.system.service.impl;

import cn.hutool.core.util.StrUtil;
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.system.mapper.PqFrontLogsMapper;
import com.njcn.system.pojo.dto.PqFrontLogsDTO;
import com.njcn.system.pojo.param.PqFrontLogsChildParam;
import com.njcn.system.pojo.param.PqFrontLogsParam;
import com.njcn.system.pojo.po.PqFrontLogs;
import com.njcn.system.pojo.po.PqFrontLogsChild;
import com.njcn.system.pojo.vo.PqFrontLogsVO;
import com.njcn.system.service.PqFrontLogsChildService;
import com.njcn.system.service.PqFrontLogsService;
import com.njcn.web.factory.PageFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Objects;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hongawen
 * @since 2021-12-13
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class PqFrontLogsServiceImpl extends ServiceImpl<PqFrontLogsMapper, PqFrontLogs> implements PqFrontLogsService {

    private final PqFrontLogsChildService pqFrontLogsChildService;
    // 创建可重入锁
    private final Lock lock = new ReentrantLock();

    @Override
    public void addFrontLogs(PqFrontLogsDTO pqFrontLogsDTO) {
        lock.lock(); // 获取锁，如果启动多实例要考虑分布式锁
        try {
                PqFrontLogs one = this.lambdaQuery()
                        .eq(PqFrontLogs::getLevel, pqFrontLogsDTO.getLevel())
                        .eq(PqFrontLogs::getNodeId, pqFrontLogsDTO.getNodeId())
                        .eq(PqFrontLogs::getFrontType, pqFrontLogsDTO.getFrontType())
                        .eq(PqFrontLogs::getCode, pqFrontLogsDTO.getCode())
                        .eq(StringUtils.isNotBlank(pqFrontLogsDTO.getBusinessId()),PqFrontLogs::getBusinessId, pqFrontLogsDTO.getBusinessId())
                        .eq(PqFrontLogs::getState,1).one();
                if(Objects.nonNull(one)){
                    one.setUpdateTime(LocalDateTime.now());
                    this.updateById(one);

                    PqFrontLogsChild pqFrontLogsChild = new PqFrontLogsChild();
                    pqFrontLogsChild.setMainId(one.getId());
                    pqFrontLogsChild.setLog(pqFrontLogsDTO.getLog());
                    pqFrontLogsChild.setGrade(pqFrontLogsDTO.getGrade());
                    pqFrontLogsChild.setState(1);


                    pqFrontLogsChildService.save(pqFrontLogsChild);
                }else {
                    PqFrontLogs pqFrontLogs = new PqFrontLogs();
                    BeanUtils.copyProperties(pqFrontLogsDTO,pqFrontLogs);
                    pqFrontLogs.setState(1);
                    this.save(pqFrontLogs);

                    PqFrontLogsChild pqFrontLogsChild = new PqFrontLogsChild();
                    pqFrontLogsChild.setMainId(pqFrontLogs.getId());
                    pqFrontLogsChild.setLog(pqFrontLogsDTO.getLog());
                    pqFrontLogsChild.setGrade(pqFrontLogsDTO.getGrade());
                    pqFrontLogsChild.setState(1);


                    pqFrontLogsChildService.save(pqFrontLogsChild);

                }
            } finally {
            lock.unlock(); // 释放锁
        }

    }

    @Override
    public Page<PqFrontLogsVO> queryPage(PqFrontLogsParam baseParam) {
        QueryWrapper<PqFrontLogs> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(baseParam.getSearchBeginTime()) && StringUtils.isNotBlank(baseParam.getSearchEndTime())) {
            queryWrapper.between("A.update_Time", baseParam.getSearchBeginTime() + " 00:00:00", baseParam.getSearchEndTime() + " 23:59:59");
        }
        String searchValue = baseParam.getSearchValue();
        String level;
        if (StrUtil.equals(searchValue, "设备")) {
            level = "terminal";
        } else if (StrUtil.equals(searchValue, "监测点")) {
            level = "measurepoint";
        } else if (StrUtil.equals(searchValue, "进程")) {
            level = "process";
        } else {
            level = null;
        }

        if (StringUtils.isNotBlank(baseParam.getSearchValue())) {
            queryWrapper.and(x -> {
                        x.like("line.name", baseParam.getSearchValue())
                        .or()
                        .like(StrUtil.isNotBlank(level),"a.level", level)
                        .or()
                        .like("sys.name", baseParam.getSearchValue());
                    }
            );
        }

        queryWrapper.eq(StringUtils.isNotBlank(baseParam.getCode()), "A.code", baseParam.getCode());
        queryWrapper.eq(StringUtils.isNotBlank(baseParam.getFrontType()), "A.front_type", baseParam.getFrontType());

        queryWrapper.orderByDesc("A.update_Time");
        Page<PqFrontLogsVO> page = this.baseMapper.page(new Page<>(PageFactory.getPageNum(baseParam), PageFactory.getPageSize(baseParam)), queryWrapper);
        page.getRecords().forEach(temp -> {
            if (Objects.equals(temp.getLevel(), "terminal")) {
                temp.setLevel("设备");
            }else if(Objects.equals(temp.getLevel(),"measurepoint")){
                temp.setLevel("监测点");
            }else if(Objects.equals(temp.getLevel(),"process")){
                temp.setLevel("进程");
            }else {
                temp.setLevel("/");
            }

            temp.setFrontType(getFrontType(temp.getFrontType()));

        });
        return page;
    }

    @Override
    public Page<PqFrontLogsChild> queryLogCHild(PqFrontLogsChildParam baseParam) {
        Page<PqFrontLogsChild> page = new Page<>(PageFactory.getPageNum(baseParam),PageFactory.getPageSize(baseParam));

        QueryWrapper<PqFrontLogsChild> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(PqFrontLogsChild::getMainId,baseParam.getMainId())
                .between(PqFrontLogsChild::getCreateTime,baseParam.getSearchBeginTime()+" 00:00:00", baseParam.getSearchEndTime()+" 23:59:59")
                .like(PqFrontLogsChild::getLog,baseParam.getSearchValue()).orderByDesc(PqFrontLogsChild::getCreateTime);

        Page<PqFrontLogsChild> page1 = pqFrontLogsChildService.page(page, queryWrapper);
        return page1;
    }

    public String getFrontType(String frontType){
        // //前置类型stat稳态/recall补招/realTime实时/comtrade
        switch (frontType) {
            case "stat":
               return "稳态";
            case "recall":
                return "补招";
            case "realTime":
                return "实时";
            case "comtrade":
                return "录波";
            default:
                return "/";

        }
    }
}
