package com.storlead.system.service.impl;

import cn.hutool.json.JSONException;
import cn.hutool.json.JSONObject;
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.storlead.system.holder.RequestHolder;
import com.storlead.system.pojo.dto.SysOperationLogDTO;
import com.storlead.system.pojo.entity.SysOperationLogEntity;
import com.storlead.system.mapper.SysOperationLogMapper;
import com.storlead.system.service.SysOperationLogService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Objects;

/**
 * <p>
 * 系统日志 服务实现类
 * </p>
 *
 * @author chenkq
 * @since 2022-07-29
 */
@Service
public class SysOperationLogServiceImpl extends ServiceImpl<SysOperationLogMapper, SysOperationLogEntity> implements SysOperationLogService {

    /**
     * 保存日志
     *
     * @param username  用户名
     * @param browser   浏览器
     * @param ipAddr    ip地址
     * @param joinPoint 切入点
     * @param sysLog    日志
     * @return java.lang.Boolean
     * @author blank
     * @date 2020-3-23 下午 12:30
     */
    @Override
    public Boolean save(String username, String browser, String ipAddr, ProceedingJoinPoint joinPoint, SysOperationLogEntity sysLog) {
        try {
            HttpServletRequest request = RequestHolder.getHttpServletRequest();
            if (request.getRequestURI().contains("list") ) {
                return true;
            }
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            ApiOperation aopLog = method.getAnnotation(ApiOperation.class);

            //方法路径
            String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()";

            StringBuilder parameter = new StringBuilder("{");
            //参数名称
            String[] argNames = signature.getParameterNames();
            //参数值
            Object[] argValues = joinPoint.getArgs();
            if (argValues != null) {
                for (int i = 0; i < argValues.length; i++) {
                    //跳过登陆密码记录
                    if (!"password".equals(argNames[i])) {
                        parameter.append(" ").append(argNames[i]).append(": ").append(argValues[i]);
                    }
                }
            }
            //请求方法
            assert sysLog != null;
            sysLog.setDescription(aopLog.value());
            sysLog.setRequestTime(LocalDateTime.now());
            sysLog.setRequestIp(ipAddr);
            String logPath = "login";
            sysLog.setRequestPath(request.getRequestURI());
            if (sysLog.getRequestPath().contains("/log/list")) {
                //不记录查看日志的结果,否则容易造成地柜记录日志数据 导致卡死mysql
                sysLog.setResult(null);
            }
            if (logPath.equals(signature.getName()) && !request.getRequestURI().contains("/login")) {
                assert argValues != null;
                try {
                    username = new JSONObject(argValues[0]).getStr("account");
                } catch (JSONException e) {
                    log.error("系统日志出错,未正确获取到请求的 username 参数 ");
                    username = "UNKNOWN";
                }
            }

            sysLog.setMethod(methodName);
            sysLog.setUserName(username);
            sysLog.setParameter(parameter.toString() + "}");
            sysLog.setBrowser(browser);
            sysLog.setResult("");
//            String address = IpUtil.getCountryName(ipAddr, null) + IpUtil.getStateName(ipAddr, null) + IpUtil.getCityName(ipAddr, null);
//            if (IpUtil.isInnerIP(ipAddr)) {
//                address = "内网IP";
//            }
//            sysLog.setAddress(address);
            save(sysLog);
        }catch (Exception e) {
            log.error("save-log-error---",e);
        }
//        ThreadPoolUtil.execute(new Runnable() {
//            @Override
//            public void run() {
//                String address = IpUtil.getCountryName(ipAddr, null) + IpUtil.getStateName(ipAddr, null) + IpUtil.getCityName(ipAddr, null);
//                if (IpUtil.isInnerIP(ipAddr)) {
//                    address = "内网IP";
//                }
//                sysLog.setAddress(address);
//                save(sysLog);
//            }
//        });
        return true;
    }

    /**
     * 获取日志列表
     * @return java.util.List<com.storlead.model.entity.Log>
     * @author blank
     * @date 2021-3-4 上午 10:10
     */
    @Override
    public IPage<SysOperationLogEntity> pageList(SysOperationLogDTO dto) {

        Page<SysOperationLogEntity> page = new Page<>(dto.getPageIndex(), dto.getPageSize());
        QueryWrapper<SysOperationLogEntity> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(dto.getUserName())) {
            queryWrapper.lambda().like(SysOperationLogEntity::getUserName, dto.getBlurry());
        }
        if (Objects.nonNull(dto.getLogType())) {
            queryWrapper.lambda().eq(SysOperationLogEntity::getLogType, dto.getLogType());
        }
//        if (StringUtils.isNotBlank(log.getSortRule())) {
//            String column = log.getSortRule().split(" ")[0];
//            String sort = log.getSortRule().split(" ")[1];
//            if (sort.toLowerCase().contains(Constants.DESC)) {
//                queryWrapper.orderByDesc(column);
//            } else if (sort.toLowerCase().contains(Constants.ASC)) {
//                queryWrapper.orderByAsc(column);
//            }
//        } else {
//            queryWrapper.orderByDesc("request_time");
//        }

        return this.page(page, queryWrapper);

    }
}
