package com.yeejoin.amos.boot.module.common.biz.event;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.yeejoin.amos.boot.module.common.api.dao.ESUserOperateLogDao;
import com.yeejoin.amos.boot.module.common.api.dto.ESUserOperateLogDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import org.typroject.tyboot.component.event.RestEvent;
import org.typroject.tyboot.component.event.RestEventHandler;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Optional;

import static com.yeejoin.amos.boot.biz.common.enums.RequestContextExtra.COMPANY_NAME;
import static com.yeejoin.amos.boot.biz.common.enums.RequestContextExtra.REAL_NAME;

/**
 * @author Administrator
 */
@Component(value = "operateLogRestEventHandler")
@Slf4j
public class OperateLogRestEventHandler extends RestEventHandler {

    @Value("${spring.application.name}")
    private String applicationName;

    private final ESUserOperateLogDao esUserOperateLogDao;

    public OperateLogRestEventHandler(ESUserOperateLogDao esUserOperateLogDao) {
        this.esUserOperateLogDao = esUserOperateLogDao;
    }

    @Override
    @Async
    protected void handleEvent(RestEvent restEvent) {
        try {
            StopWatch watch = new StopWatch();
            watch.start();
            Date date = new Date();
            ESUserOperateLogDto userOperateLogDto = new ESUserOperateLogDto();
            userOperateLogDto.setCreateDate(date.getTime());
            userOperateLogDto.setTraceId(restEvent.getRequestContextModel().getTraceId());
            userOperateLogDto.setRemoteIp(restEvent.getRequestContextModel().getRequestIP());
            userOperateLogDto.setMethodName(restEvent.getMethodName());
            userOperateLogDto.setMethodLabel(restEvent.getMethodLabel());
            userOperateLogDto.setUserId(restEvent.getRequestContextModel().getExcutedUserId());
            userOperateLogDto.setParams(JSONObject.toJSONString(restEvent.getParams()));
            userOperateLogDto.setResult(JSONObject.toJSONString(restEvent.getSource()));
            userOperateLogDto.setServiceIp(InetAddress.getLocalHost().getHostAddress());
            userOperateLogDto.setServiceName(applicationName);
            userOperateLogDto.setRequestTimeMills(restEvent.getRequestContextModel().getRequestTimeMills());
            userOperateLogDto.setAppKey(restEvent.getRequestContextModel().getAppKey());
            userOperateLogDto.setToken(restEvent.getRequestContextModel().getToken());
            userOperateLogDto.setProduct(restEvent.getRequestContextModel().getProduct());
            userOperateLogDto.setLoginId(restEvent.getRequestContextModel().getLoginId());
            userOperateLogDto.setRequestDate(DateUtil.formatDateTime(date));
            userOperateLogDto.setRealName(Optional.ofNullable(restEvent.getRequestContextModel().getAttribute(REAL_NAME)).map(Object::toString).orElse(""));
            userOperateLogDto.setCompanyName(Optional.ofNullable(restEvent.getRequestContextModel().getAttribute(COMPANY_NAME)).map(Object::toString).orElse(""));
            esUserOperateLogDao.save(userOperateLogDto);
            watch.stop();
            log.info("用户操作日志写入es耗时：{}秒", watch.getTotalTimeSeconds());
        } catch (UnknownHostException e) {
            log.error(e.getMessage());
        }
    }
}
