package com.zhongshu.card.server.core.service.user;

import com.github.microservice.components.data.base.util.PageEntityUtil;
import com.github.microservice.components.data.mongo.mongo.domain.SuperEntity;
import com.zhongshu.card.client.model.operLogs.OperationLogsAddParam;
import com.zhongshu.card.client.model.operLogs.OperationLogsModel;
import com.zhongshu.card.client.model.operLogs.OperationLogsSearchParam;
import com.github.microservice.net.ResultContent;
import com.zhongshu.card.client.type.LogsLevel;
import com.zhongshu.card.server.core.dao.org.UserCountDao;
import com.zhongshu.card.server.core.dao.user.OperationLogsDao;
import com.zhongshu.card.server.core.domain.operlog.OperationLogs;
import com.zhongshu.card.server.core.domain.org.UserAccount;
import com.zhongshu.card.server.core.service.base.SuperService;
import com.zhongshu.card.server.core.util.BeanUtils;
import com.zhongshu.card.client.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * @author TRX
 * @date 2024/5/24
 */
@Slf4j
@Service
public class OperationLogsService extends SuperService {
    @Autowired
    OperationLogsDao operationLogsDao;

    @Autowired
    UserCountDao userDao;

    // 保存60天
    private static Long ttlTime = 60 * 24 * 60 * 60 * 1000L;

    public void addLog(OperationLogsAddParam param) {
        CompletableFuture.runAsync(() -> {
            OperationLogs logs = new OperationLogs();
            BeanUtils.copyProperties(param, logs);
            logs.setTime(DateUtils.paresTime(System.currentTimeMillis(), DateUtils.FORMAT_LONG));
            logs.setTtl(new Date(System.currentTimeMillis() + ttlTime));
            if (StringUtils.isNotEmpty(param.getUid())) {
                UserAccount userAccount = userDao.findTopByUserId(param.getUid());
                if (ObjectUtils.isNotEmpty(userAccount)) {
                    logs.setUserName(userAccount.getName());
                    logs.setLoginName(userAccount.getLoginName());
                }
            }
            operationLogsDao.save(logs);
        });
    }

    public ResultContent addLogs(String content, LogsLevel level) {
        OperationLogs logs = new OperationLogs();
        initEntityNoCheckOid(logs);
        logs.setContent(content);
        if (level == null) {
            level = LogsLevel.Low;
        }
        logs.setLevel(level);
        logs.setTime(DateUtils.paresTime(System.currentTimeMillis(), DateUtils.FORMAT_LONG));
        logs.setTtl(new Date(System.currentTimeMillis() + ttlTime));
        operationLogsDao.save(logs);
        return ResultContent.buildSuccess();
    }

    public ResultContent addLogs(String content, LogsLevel level, SuperEntity entity) {
        OperationLogs logs = new OperationLogs();
        initEntityNoCheckOid(logs);
        logs.setContent(content);
        if (level == null) {
            level = LogsLevel.Low;
        }
        logs.setLevel(level);
        logs.setTime(DateUtils.paresTime(System.currentTimeMillis(), DateUtils.FORMAT_LONG));
        if (ObjectUtils.isNotEmpty(entity)) {
            logs.setDataId(entity.getId());
            logs.setBackObj(entity);
        }
        logs.setTtl(new Date(System.currentTimeMillis() + ttlTime));
        operationLogsDao.save(logs);
        return ResultContent.buildSuccess();
    }

    /**
     * 日志列表
     *
     * @param pageable
     * @param param
     * @return
     */
    public ResultContent<Page<OperationLogsModel>> pageLogs(Pageable pageable, OperationLogsSearchParam param) {
        Page<OperationLogs> page = operationLogsDao.page(pageable, param);
        return ResultContent.buildSuccess(PageEntityUtil.toPageModel(page, this::toModel));
    }

    public OperationLogsModel toModel(OperationLogs entity) {
        OperationLogsModel model = new OperationLogsModel();
        if (ObjectUtils.isNotEmpty(entity)) {
            BeanUtils.copyProperties(entity, model);
        }
        return model;
    }

}
