package com.css.simulation.resource.server.app.service;

import api.common.pojo.constants.DictConstants;
import api.common.pojo.constants.LogConstants;
import api.common.pojo.param.log.LogPageParam;
import api.common.pojo.param.model.VehiclePageParam;
import api.common.pojo.param.scene.SystemUserSceneParam;
import api.common.pojo.po.log.LogLoginPO;
import api.common.pojo.po.log.LogOperationPO;
import api.common.pojo.po.log.LogSystemPO;
import api.common.pojo.po.model.VehicleTempPO;
import api.common.pojo.po.scene.SystemScenePackagePO;
import api.common.pojo.po.system.ClusterPO;
import api.common.pojo.po.system.ParameterPO;
import api.common.pojo.po.system.UserPO;
import api.common.pojo.vo.model.VehicleTempVO;
import api.common.pojo.vo.scene.UserSceneVO;
import api.common.pojo.vo.system.UserVO;
import api.common.util.ObjectUtil;
import api.common.util.StringUtil;
import api.common.util.TimeUtil;
import com.css.simulation.resource.server.infra.util.AuthUtil;
import com.css.simulation.resource.server.infra.util.PageUtil;
import com.css.simulation.resource.server.infra.db.mysql.mapper.LogMapper;
import com.css.simulation.resource.server.infra.db.mysql.mapper.SystemUserMapper;
import com.css.simulation.resource.server.infra.db.mysql.mapper.VehicleTempMapper;
import com.github.pagehelper.PageInfo;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


@Service
public class LogService {

    @Resource
    private LogMapper logMapper;

    @Resource
    private DictService dictService;

    @Resource
    private SystemUserMapper systemUserMapper;

    @Resource
    private VehicleTempMapper vehicleTempMapper;

    /**
     * 保存普通操作日志（异步）
     */
    @Async
    public void saveOperationLog(LogOperationPO po) {
        po.setId(StringUtil.getRandomUUID());
        po.setCreateTime(TimeUtil.getNowForMysql());
        logMapper.insertOperationLog(po);
    }

    /**
     * 查询登录日志
     */
    public PageInfo<LogLoginPO> getLoginLogPageList(LogPageParam pageParam) {
        PageUtil.setPageInfo(pageParam);
        List<LogLoginPO> list = logMapper.getLoginLogPageList(pageParam);
        return new PageInfo<>(list);
    }

    /**
     * 查询普通操作日志
     */
    public PageInfo<LogOperationPO> getOperationLogPageList(LogPageParam pageParam) {
        PageUtil.setPageInfo(pageParam);
        List<LogOperationPO> list = new ArrayList<>();
        String roleCode = AuthUtil.getCurrentUserRoleCode();
        if (DictConstants.ROLE_CODE_UESR.equals(roleCode)) {//普通用户
            String currentUserId = AuthUtil.getCurrentUserId();
            pageParam.setContent(currentUserId);//借用该字段传递当前用户id
            list = logMapper.getUserOperationLogPageList(pageParam);
        } else {//管理员
            list = logMapper.getOperationLogPageList(pageParam);
        }
        //字典翻译
        Map<String, Map<String, String>> dictMaps = dictService.getDictMapsByTypes(LogConstants.MODULE_TYPE + "," + LogConstants.OPERATION_TYPE);
        list.forEach(po -> {
            po.setModule(dictMaps.get(LogConstants.MODULE_TYPE).get(po.getModule()));
            po.setOperationType(dictMaps.get(LogConstants.OPERATION_TYPE).get(po.getOperationType()));
        });
        return new PageInfo<>(list);
    }

    /**
     * 查询系统管理日志
     */
    public PageInfo<LogSystemPO> getSystemLogPageList(LogPageParam pageParam) {
        PageUtil.setPageInfo(pageParam);
        List<LogSystemPO> list = logMapper.getSystemLogPageList(pageParam);
        //字典翻译
        Map<String, Map<String, String>> dictMaps = dictService.getDictMapsByTypes(LogConstants.SYS_LOG_TYPE + "," + DictConstants.ROLE_CODE);
        list.forEach(po -> {
            po.setModule(dictMaps.get(LogConstants.SYS_LOG_TYPE).get(po.getModule()));
            po.setOperationType(dictMaps.get(LogConstants.SYS_LOG_TYPE).get(po.getOperationType()));
            po.setRoleCode(dictMaps.get(DictConstants.ROLE_CODE).get(po.getRoleCode()));
        });
        return new PageInfo<>(list);
    }

    /**
     * 记录用户管理模块日志
     */
    public void logUser(String operationType, UserPO userPO) {
        try {
            LogSystemPO po = getLogSystemPO(LogConstants.SYS_LOG_USER, operationType);
            String userId = userPO.getId();
            String username = userPO.getUsername();
            if (ObjectUtil.isNull(username)) {
                UserVO userVO = systemUserMapper.getUserInfo(userId);
                username = userVO.getUsername();
            }
            String content = username + " ( ID: " + userId + " )";
            po.setContent(content);
            logMapper.insertSystemLog(po);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 记录车辆模板管理模块日志
     */
    public void logVehicle(String operationType, VehicleTempPO vehicleTempPO) {
        try {
            LogSystemPO po = getLogSystemPO(LogConstants.SYS_LOG_VEHICLE, operationType);
            String vehicleTempId = vehicleTempPO.getId();
            String modelLabel = vehicleTempPO.getModelLabel();
            if (ObjectUtil.isNull(modelLabel)) {
                VehiclePageParam param = new VehiclePageParam();
                param.setId(vehicleTempId);
                VehicleTempVO vehicleTempInfo = vehicleTempMapper.getVehicleTempInfo(param);
                modelLabel = vehicleTempInfo.getModelLabel();
            }
            String content = modelLabel + " ( ID: " + vehicleTempId + " )";
            po.setContent(content);
            logMapper.insertSystemLog(po);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 记录参数管理模块日志
     */
    public void logParameter(String operationType, ParameterPO parameterPO) {
        try {
            LogSystemPO po = getLogSystemPO(LogConstants.SYS_LOG_PARAM, operationType);
            String paramId = parameterPO.getId();
            String userId = parameterPO.getUserId();
            String userName = parameterPO.getUserName();
            String content = "账户：" + userName + " ( ID: " + userId + " ); 参数配置" + " ( ID: " + paramId + " )";
            po.setContent(content);
            logMapper.insertSystemLog(po);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 记录集群管理模块日志
     */
    public void logCluster(String operationType, ClusterPO clusterPO) {
        try {
            LogSystemPO po = getLogSystemPO(LogConstants.SYS_LOG_CLUSTER, operationType);
            String clusterId = clusterPO.getId();
            String userId = clusterPO.getUserId();
            String userName = clusterPO.getUserName();
            String content = "账户：" + userName + " ( ID: " + userId + " ); 节点配置" + " ( ID: " + clusterId + " )";
            po.setContent(content);
            logMapper.insertSystemLog(po);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取系统管理日志对象
     */
    private LogSystemPO getLogSystemPO(String module, String operationType) {
        LogSystemPO po = new LogSystemPO();
        po.setId(StringUtil.getRandomUUID());
        po.setCreateTime(TimeUtil.getNowForMysql());
        po.setUserId(AuthUtil.getCurrentUserId());
        po.setUsername(AuthUtil.getCurrentUsername());
        po.setRoleCode(AuthUtil.getCurrentUserRoleCode());
        po.setModule(module);
        po.setOperationType(operationType);
        return po;
    }

    /**
     * 记录场景包模块日志
     */
    public void logScenePackage(String operationType, SystemScenePackagePO packagePO, SystemUserSceneParam params) {
        try {
            LogSystemPO po = getLogSystemPO(LogConstants.SYS_LOG_PACKAGE, operationType);
            //获取当前登录人姓名
            String content = null;
            if (operationType.equals(LogConstants.SYS_LOG_PACKAGE_DELETE)) {
                content = "删除场景包：" + packagePO.getPackageName() + "(ID:" + packagePO.getId() + ")";
            } else if (operationType.equals(LogConstants.SYS_LOG_PACKAGE_UPDATE)) {
                content = "编辑场景包：" + packagePO.getPackageName() + "(ID:" + packagePO.getId() + ")";
            } else if (operationType.equals(LogConstants.SYS_LOG_PACKAGE_INSERT)) {
                content = "创建场景包：" + packagePO.getPackageName() + "(ID:" + packagePO.getId() + ")";
            } else if (operationType.equals(LogConstants.SYS_LOG_PACKAGE_DISTRIBUTION)) {
                List<UserSceneVO> users = params.getUserIds();
                StringBuffer sb = new StringBuffer();
                for (UserSceneVO vo : users) {
                    sb.append("、").append(vo.getUserName()).append("((ID:").append(vo.getUserId()).append(")");
                }
                sb.deleteCharAt(0);
                content = "分配场景包：" + params.getPackageName() + "(ID:" + params.getPackageId() + ")给用户：" + sb.toString();
            } else if (operationType.equals(LogConstants.SYS_LOG_PACKAGE_DISTRIBUTION_DELETE)) {
                List<UserSceneVO> users = params.getUserIds();
                StringBuffer sb = new StringBuffer();
                for (UserSceneVO vo : users) {
                    sb.append("、").append(vo.getUserName()).append("((ID:").append(vo.getUserId()).append(")");
                }
                sb.deleteCharAt(0);
                content = "分配场景包：" + params.getPackageName() + "(ID:" + params.getPackageId() + ")时移除用户：" + sb.toString();
            }
            po.setContent(content);
            logMapper.insertSystemLog(po);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 记录场景包分配模块日志
     */
    public void logSystemUserSceneByPackageId(String operationType, SystemUserSceneParam param, String packageCount) {
        try {
            LogSystemPO po = getLogSystemPO(LogConstants.SYS_LOG_PACKAGE_GRANT, operationType);
            String content = param.getUserName() + "(ID" + param.getUserId() + ")" + "分配场景包：" + packageCount;
            po.setContent(content);
            logMapper.insertSystemLog(po);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 记录场景库管理模块日志
     */
    public void logSceneDelete(String operationType, Map map) {
        try {
            LogSystemPO po = getLogSystemPO(LogConstants.SYS_LOG_SCENE, operationType);
            Map<String, String> mapType = dictService.getDictMapByType(DictConstants.SCENE_TYPE);
            String content = "删除" + mapType.get(map.get("type")) + ":" + map.get("sceneName");
            po.setContent(content);
            logMapper.insertSystemLog(po);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 记录场景上传模块日志
     */
    public void logSceneUpload(String operationType, String content) {
        try {
            LogSystemPO po = getLogSystemPO(LogConstants.SYS_LOG_SCENE_TASK, operationType);
            //获取当前登录人姓名
            po.setContent(content);
            logMapper.insertSystemLog(po);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
