package com.sunyard.ssp.modules.monitor.log.serviceimpl;

import cn.hutool.core.collection.CollectionUtil;
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.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunyard.ssp.modules.monitor.log.entity.AuditLog;
import com.sunyard.ssp.modules.monitor.log.entity.AuditLogSign;
import com.sunyard.ssp.modules.monitor.log.mapper.AuditLogMapper;
import com.sunyard.ssp.modules.monitor.log.mapper.AuditLogSignMapper;
import com.sunyard.ssp.modules.monitor.log.service.IAuditLogService;
import com.sunyard.ssp.modules.user.entity.ScUser;
import com.sunyard.ssp.utils.DateUtil;
import com.sunyard.ssp.vo.SearchVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author fyc
 * @since 2020-03-18
 */
@Slf4j
@Service
@Transactional
public class AuditLogServiceImpl extends ServiceImpl<AuditLogMapper, AuditLog> implements IAuditLogService {

    @Autowired
    private AuditLogMapper auditLogMapper;

    @Autowired
    private AuditLogSignMapper auditLogSignMapper;

    @Override
    public IPage<AuditLog> queryList(Integer pageNumber, Integer pageSize,
                                     String operateContent, String operateType,
                                     String requestMethod, String readUserName,
                                     String startTime, String endTime) {

        Page<AuditLog> auditLogPage = new Page<>(pageNumber, pageSize);
        IPage<AuditLog> auditLogIPage = auditLogPage.setRecords(auditLogMapper.queryList(auditLogPage, operateContent, operateType, requestMethod, readUserName, DateUtil.StringToDateOrNull(startTime), DateUtil.StringToDateOrNull(endTime)));
        return auditLogIPage;
    }

    @Override
    public IPage<AuditLog> userLogQueryList(Integer pageNumber, Integer pageSize,
                                     String operateContent, String operateType,
                                     String requestMethod, String readUserName,
                                     String startTime, String endTime) {

        Page<AuditLog> auditLogPage = new Page<>(pageNumber, pageSize);
        IPage<AuditLog> auditLogIPage = auditLogPage.setRecords(auditLogMapper.userLogQueryList(auditLogPage, operateContent, operateType, requestMethod, readUserName, DateUtil.StringToDateOrNull(startTime), DateUtil.StringToDateOrNull(endTime)));
        return auditLogIPage;
    }

    @Override
    public List<AuditLog> queryList(String operateContent, String operateType, String readStatus, String readUserName, String startTime, String endTime) {
        return auditLogMapper.queryList(operateContent, operateType, readStatus, readUserName, DateUtil.StringToDateOrNull(startTime), DateUtil.StringToDateOrNull(endTime));
    }

    @Override
    public List<AuditLog> userLogQueryListWithOutPage(String operateContent, String operateType, String readStatus, String readUserName, String startTime, String endTime) {
        return auditLogMapper.userLogQueryListWithOutPage(operateContent, operateType, readStatus, readUserName, DateUtil.StringToDateOrNull(startTime), DateUtil.StringToDateOrNull(endTime));
    }

    @Override
    public Boolean truncateTable() {
        Integer i = auditLogMapper.truncateTable();
        if (i < 0) {
            return false;
        }
        return true;
    }

    @Override
    public Boolean updateReadStatus(Integer[] ids, ScUser scUser) {
        Boolean result = true;
        for (Integer id : ids) {
            AuditLog auditLog = auditLogMapper.selectById(id);
            if (auditLog.getReadStatus() == 0) {
                auditLog.setReadStatus(1);
                auditLog.setReadUserId(scUser.getId());
                auditLog.setReadUserName(scUser.getRealname());
                Integer i = auditLogMapper.updateById(auditLog);
                if (i < 1) {
                    result = false;
                    break;
                }
            }
        }
        return result;
    }

    @Override
    public List<AuditLog> getByLogSignId(Long signId) {
        List<AuditLogSign> logSigns = auditLogSignMapper.selectList(new QueryWrapper<AuditLogSign>().lambda().eq(AuditLogSign::getSignId, signId));
        if (CollectionUtil.isEmpty(logSigns)) {
            return null;
        }
        List<Long> ids = logSigns.stream().map(AuditLogSign::getLogId).collect(Collectors.toList());
        return baseMapper.selectList(new QueryWrapper<AuditLog>().lambda().in(AuditLog::getId, ids).orderByAsc(AuditLog::getId));
    }

    @Override
    public org.springframework.data.domain.Page<AuditLog> queryNeedSignLog(AuditLog auditLog, SearchVo searchVo, Pageable pageable) {
        LambdaQueryWrapper<AuditLog> wrapper = new QueryWrapper<AuditLog>().lambda();
        if (StrUtil.isNotBlank(auditLog.getOperateContent())) {
            wrapper.like(AuditLog::getOperateContent, auditLog.getOperateContent());
        }
        if (StrUtil.isNotBlank(auditLog.getOperateType())) {
            wrapper.like(AuditLog::getOperateType, auditLog.getOperateType());
        }
        if (StrUtil.isNotBlank(auditLog.getRequestMothed())) {
            wrapper.eq(AuditLog::getRequestMothed, auditLog.getRequestMothed());
        }
        if (StrUtil.isNotBlank(auditLog.getReadUserName())) {
            wrapper.like(AuditLog::getReadUserName, auditLog.getReadUserName());
        }
        //创建时间
        if (StrUtil.isNotBlank(searchVo.getStartDate()) && StrUtil.isNotBlank(searchVo.getEndDate())) {
            Date start = cn.hutool.core.date.DateUtil.parse(searchVo.getStartDate());
            Date end = cn.hutool.core.date.DateUtil.parse(searchVo.getEndDate());
            wrapper.between(AuditLog::getCreateTime, start, cn.hutool.core.date.DateUtil.endOfDay(end));
        }
        wrapper.eq(AuditLog::getReadStatus, 1);
        //过滤已签名的日志
        List<AuditLogSign> auditLogSigns = auditLogSignMapper.selectList(null);
        if (CollectionUtil.isNotEmpty(auditLogSigns)) {
            List<Long> logids = auditLogSigns.stream().map(AuditLogSign::getLogId).collect(Collectors.toList());
            wrapper.notIn(AuditLog::getId, logids);
        }
        wrapper.orderByDesc(AuditLog::getCreateTime);
        IPage page = new Page<>(pageable.getPageNumber() + 1, pageable.getPageSize());
        IPage auditLogList = baseMapper.selectPage(page, wrapper);

        org.springframework.data.domain.Page<AuditLog> res = new PageImpl<AuditLog>(auditLogList.getRecords(), pageable, auditLogList.getTotal());
        return res;
    }


    @Override
    public org.springframework.data.domain.Page<AuditLog> userLoginQueryNeedSignLog(AuditLog auditLog, SearchVo searchVo, Pageable pageable) {
        LambdaQueryWrapper<AuditLog> wrapper = new QueryWrapper<AuditLog>().lambda();
        wrapper.like(AuditLog::getOperateType, "登录");

        if (StrUtil.isNotBlank(auditLog.getReadUserName())) {
            wrapper.like(AuditLog::getReadUserName, auditLog.getReadUserName());
        }
        //创建时间
        if (StrUtil.isNotBlank(searchVo.getStartDate()) && StrUtil.isNotBlank(searchVo.getEndDate())) {
            Date start = cn.hutool.core.date.DateUtil.parse(searchVo.getStartDate());
            Date end = cn.hutool.core.date.DateUtil.parse(searchVo.getEndDate());
            wrapper.between(AuditLog::getCreateTime, start, cn.hutool.core.date.DateUtil.endOfDay(end));
        }
        wrapper.eq(AuditLog::getReadStatus, 1);
        //过滤已签名的日志
        List<AuditLogSign> auditLogSigns = auditLogSignMapper.selectList(null);
        if (CollectionUtil.isNotEmpty(auditLogSigns)) {
            List<Long> logids = auditLogSigns.stream().map(AuditLogSign::getLogId).collect(Collectors.toList());
            wrapper.notIn(AuditLog::getId, logids);
        }
        wrapper.orderByDesc(AuditLog::getCreateTime);
        IPage page = new Page<>(pageable.getPageNumber() + 1, pageable.getPageSize());
        IPage auditLogList = baseMapper.selectPage(page, wrapper);

        org.springframework.data.domain.Page<AuditLog> res = new PageImpl<AuditLog>(auditLogList.getRecords(), pageable, auditLogList.getTotal());
        return res;
    }
}
