package com.hfkj.service.user.impl;

import com.alibaba.fastjson.JSONObject;
import com.hfkj.common.utils.AmapApiService;
import com.hfkj.common.utils.RequestUtils;
import com.hfkj.dao.BsUserLoginLogMapper;
import com.hfkj.entity.*;
import com.hfkj.service.user.BsUserLoginLogService;
import com.hfkj.sysenum.SecUserLoginLogStatusEnum;
import com.hfkj.sysenum.UserLoginPlatform;
import com.hfkj.sysenum.UserLoginType;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @className: BsUserLoginLogServiceImpl
 * @author: HuRui
 * @date: 2024/5/6
 **/
@Service("userLoginLogService")
public class BsUserLoginLogServiceImpl implements BsUserLoginLogService {
    @Resource
    private BsUserLoginLogMapper userLoginLogMapper;

    @Override
    public void create(BsUserLoginLog userLoginLog) {
        userLoginLog.setCreateTime(new Date());
        userLoginLogMapper.insert(userLoginLog);
    }

    @Override
    public void asyncCreateLog(UserLoginPlatform loginPlatform, UserLoginType loginType,  BsUser user, HttpServletRequest request) {
        // 创建一个单线程的线程池
        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        // 异步记录登录信息
        singleThreadExecutor.submit(new Runnable() {
            @Override
            public void run() {
                BsUserLoginLog loginLog = new BsUserLoginLog();
                loginLog.setPlatformCode(loginPlatform.getCode());
                loginLog.setPlatformName(loginPlatform.getName());
                loginLog.setLoginTypeCode(loginType.getCode());
                loginLog.setLoginTypeName(loginType.getName());
                loginLog.setUserId(user.getId());
                loginLog.setIp(RequestUtils.getIpAddress(request));
                // 查询ip归属地
                JSONObject ipAddress = AmapApiService.queryIp(loginLog.getIp());
                if (ipAddress != null) {
                    loginLog.setRegionName(StringUtils.isNotBlank(ipAddress.getString("province"))?ipAddress.getString("province"):"未知");
                    loginLog.setCityId(StringUtils.isNotBlank(ipAddress.getString("adcode"))?ipAddress.getString("adcode"):null);
                    loginLog.setCityName(StringUtils.isNotBlank(ipAddress.getString("city"))?ipAddress.getString("city"):"未知");
                    loginLog.setStatus(SecUserLoginLogStatusEnum.status1.getCode());
                } else {
                    loginLog.setCountry("未知");
                    loginLog.setRegionName("未知");
                    loginLog.setCityName("未知");
                    loginLog.setIsp("未知");
                    loginLog.setStatus(SecUserLoginLogStatusEnum.status2.getCode());
                }
                create(loginLog);
            }
        });
        singleThreadExecutor.shutdown();
    }

    @Override
    public List<BsUserLoginLog> getLogList(Map<String, Object> param) {
        BsUserLoginLogExample example = new BsUserLoginLogExample();
        BsUserLoginLogExample.Criteria criteria = example.createCriteria();

        if (MapUtils.getLong(param, "userId") != null) {
            criteria.andUserIdEqualTo(MapUtils.getLong(param, "userId"));
        }

        if (MapUtils.getInteger(param, "status") != null) {
            criteria.andStatusEqualTo(MapUtils.getInteger(param, "status"));
        }

        example.setOrderByClause("create_time desc");
        return userLoginLogMapper.selectByExample(example);
    }

    @Override
    public BsUserLoginLog findUserLog(Long userId) {
        BsUserLoginLogExample example = new BsUserLoginLogExample();
        example.createCriteria().andUserIdEqualTo(userId);
        example.setOrderByClause("create_time desc");

        List<BsUserLoginLog> list = userLoginLogMapper.selectByExample(example);

        if (!list.isEmpty()) {
            return list.get(0);
        }

        return null;
    }
}
