package cn.common.service.impl;

import cn.common.common.constants.BaseConstant;
import cn.common.common.redis.RedisRepository;
import cn.common.common.utils.alibaba.AliOssComponent;
import cn.common.common.utils.collection.CollectionUtils;
import cn.common.common.utils.common.CheckParam;
import cn.common.common.utils.common.DateTimeUtil;
import cn.common.interaction.helper.PageBuilder;
import cn.common.interaction.req.log.PlatformApiLogReq;
import cn.common.interaction.resp.log.ApiLogResp;
import cn.common.interaction.resp.log.ApiLogStatisticsResp;
import cn.common.interaction.resp.log.PlatformApiLogResp;
import cn.common.interaction.resp.page.Pagination;
import cn.common.repository.entity.PlatformApiLog;
import cn.common.repository.repository.PlatformApiLogRepository;
import cn.common.service.AuthUserService;
import cn.common.service.PlatformApiLogService;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Singer create by singer email:singer-coder@qq.com
 * @projectName health-platform-api
 * @Description:
 * @date 2020-01-10
 */
@Service("logService")
@Slf4j
public class PlatformApiLogServiceImpl implements PlatformApiLogService {

    @Resource
    private BaseConstant baseConstant;

    @Resource
    private RedisRepository redisRepository;

    @Resource
    private AliOssComponent aliOssComponent;

    @Resource
    private AuthUserService authUserService;

    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Resource
    private PlatformApiLogRepository platformApiLogRepository;


    /**
      * 根据参数统计访问量
      * @author: create by singer - Singer email:singer-coder@qq.com
      * @date 2022/4/11
      * @param req 查询参数
      * @return
      */
    @Override
    public List<ApiLogStatisticsResp> statisticsVisitCount(PlatformApiLogReq req){
        log.info(">>>>>>>>>>>>>>>>>>统计系统日志请求参数<<<<<<<<<<<<<:"+ JSON.toJSONString(req));
        List<ApiLogStatisticsResp> respList = Lists.newArrayList();
        LambdaQueryWrapper<PlatformApiLog> wrapper = new LambdaQueryWrapper<>();
        setPageCriteria(wrapper,req);
        List<PlatformApiLog> platformApiLogList = platformApiLogRepository.selectList(wrapper);
        if(CollectionUtils.isEmpty(platformApiLogList)){
            return Lists.newArrayList();
        }
        List<ApiLogResp> entityList = Lists.newArrayList();
        platformApiLogList = platformApiLogList.stream().sorted(Comparator.comparing(PlatformApiLog::getCreateTime)).collect(
                Collectors.toList());
        //去除时分秒
        platformApiLogList.stream().forEachOrdered(item -> {
            ApiLogResp result = new ApiLogResp();
            LocalDateTime createTime = item.getCreateTime();
            String time = DateTimeUtil.convertTimeToString(DateTimeUtil.DAY_DATETIME_PATTERN, createTime);
            createTime.withHour(BigInteger.ZERO.intValue()).withMinute(BigInteger.ZERO.intValue()).withSecond(BigInteger.ZERO.intValue());
            result.setCreateTime(time);
            result.setId(item.getId());
            entityList.add(result);
        });
        Map<String, Long> apiLogHashMap = entityList.stream().collect(
                Collectors.groupingBy(ApiLogResp::getCreateTime, Collectors.counting()));
        apiLogHashMap.forEach((key,value) -> {
            ApiLogStatisticsResp resp = new ApiLogStatisticsResp();
            resp.setVisitCount(value);
            resp.setCreateTime(key);
            respList.add(resp);
        });
        return respList;
    }

    /**
     * 设置分页条件
     * @author: create by singer - Singer email:singer-coder@qq.com
     * @date 2021/5/31
     * @param pageWrapper 查询条件
     * @param pageReq 分页插件
     * @return
     */
    private void setPageCriteria(LambdaQueryWrapper<PlatformApiLog> pageWrapper, PlatformApiLogReq pageReq){

        if(!CheckParam.isNull(pageReq.getOperation())){
            pageWrapper.eq(PlatformApiLog::getOperation,"%"+pageReq.getOperation());
        }

        if(!CheckParam.isNull(pageReq.getBeginTime())){
            pageWrapper.ge(PlatformApiLog::getCreateTime,pageReq.getBeginTime());
        }

        if(!CheckParam.isNull(pageReq.getEndTime())){
            pageWrapper.le(PlatformApiLog::getCreateTime,pageReq.getEndTime());
        }

        if(!CheckParam.isNull(pageReq.getUserName())){
            pageWrapper.eq(PlatformApiLog::getUserName,"%"+pageReq.getUserName());
        }
    }

    /**
      * 分页查询系统日志
      * @author: create by singer - Singer email:singer-coder@qq.com
      * @date 2020-01-10
      * @param pageReq 系统API日志查询请求Req
      * @return Pagination
      */
    @Override
    public Pagination<PlatformApiLogResp> queryByPage(PlatformApiLogReq pageReq){
        log.info(">>>>>>>>>>>>>>>>>>分页查询系统日志请求参数<<<<<<<<<<<<<:"+ JSON.toJSONString(pageReq));
        //构建查询条件
        LambdaQueryWrapper<PlatformApiLog> queryWrapper = new LambdaQueryWrapper<>();
        if(!CheckParam.isNull(pageReq.getUserName())){
            queryWrapper.eq(PlatformApiLog::getUserName,pageReq.getUserName());
        }
        if(!CheckParam.isNull(pageReq.getOperation())){
            queryWrapper.like(PlatformApiLog::getOperation,pageReq.getOperation());
        }
        //开始分页
        Page<Object> page = PageHelper.startPage(pageReq.getCurrentPage(), pageReq.getItemsPerPage());
        List<PlatformApiLog> entityList = platformApiLogRepository.selectList(queryWrapper);
        if(CollectionUtils.isEmpty(entityList)) {
            return PageBuilder.buildPageResult(page,entityList);
        }
        List<PlatformApiLogResp> respList = new ArrayList<>();
        entityList.stream().forEach(u1 -> {
            PlatformApiLogResp resp = new PlatformApiLogResp();
            resp.setLocation(u1.getLocation());
            resp.setMethod(u1.getMethod());
            resp.setOperation(u1.getOperation());
            resp.setParams(u1.getParams());
            resp.setRequestIp(u1.getRequestIp());
            resp.setSystemApiLogId(u1.getPlatformApiLogId());
            resp.setTime(u1.getTime());
            resp.setUserName(u1.getUserName());
            resp.setCreateTime(u1.getCreateTime());
            respList.add(resp);
        });
        return PageBuilder.buildPageResult(page,respList);
    }
}
