package com.hfkj.service.user.impl;

import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.security.AESEncodeUtil;
import com.hfkj.common.security.SessionObject;
import com.hfkj.common.security.UserCenter;
import com.hfkj.dao.BsUserMapper;
import com.hfkj.entity.BsUser;
import com.hfkj.entity.BsUserCard;
import com.hfkj.entity.BsUserExample;
import com.hfkj.model.SecUserSessionObject;
import com.hfkj.model.UserSessionObject;
import com.hfkj.service.card.BsUserCardService;
import com.hfkj.service.user.BsUserLoginLogService;
import com.hfkj.service.user.BsUserService;
import com.hfkj.sysenum.UserCardTypeEnum;
import com.hfkj.sysenum.UserLoginPlatform;
import com.hfkj.sysenum.UserLoginType;
import com.hfkj.sysenum.UserStatusEnum;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

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

/**
 * @className: BsUserServiceImpl
 * @author: HuRui
 * @date: 2024/5/6
 **/
@Service("userService")
public class BsUserServiceImpl implements BsUserService {

    @Resource
    private BsUserMapper userMapper;
    @Resource
    private UserCenter userCenter;
    @Resource
    private BsUserCardService userCardService;
    @Resource
    private BsUserLoginLogService userLoginLogService;
    @Override
    public void editData(BsUser data) {
        data.setUpdateTime(new Date());
        if (data.getId() == null) {
            data.setCreateTime(new Date());
            userMapper.insert(data);
        } else {
            userMapper.updateByPrimaryKey(data);
        }
    }

    @Override
    public void insertUserBatch(List<BsUser> data) {
        userMapper.insertUserList(data);
    }

    @Override
    public void updateUserBatch(List<BsUser> data) {
        userMapper.updateUserList(data);
    }

    @Override
    public BsUser getUser(Long userId) {
        return userMapper.selectByPrimaryKey(userId);
    }

    @Override
    public BsUser getUser(String phone) {
        BsUserExample example = new BsUserExample();
        example.createCriteria()
                .andPhoneEqualTo(phone)
                .andStatusNotEqualTo(UserStatusEnum.status0.getCode());
        List<BsUser> list = userMapper.selectByExample(example);
        if (!list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public BsUser getUserByMaOpenId(String maOpenId) {
        BsUserExample example = new BsUserExample();
        example.createCriteria()
                .andWxMaOpenidEqualTo(maOpenId)
                .andStatusNotEqualTo(UserStatusEnum.status0.getCode());
        List<BsUser> list = userMapper.selectByExample(example);
        if (!list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public BsUser getUserByOutsideOpenid(String outsideOpenid) {
        BsUserExample example = new BsUserExample();
        example.createCriteria()
                .andOutsideOpenidEqualTo(outsideOpenid)
                .andStatusNotEqualTo(UserStatusEnum.status0.getCode());
        List<BsUser> list = userMapper.selectByExample(example);
        if (!list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public List<BsUser> getList(Map<String, Object> param) {
        BsUserExample example = new BsUserExample();
        BsUserExample.Criteria criteria = example.createCriteria()
                .andStatusNotEqualTo(UserStatusEnum.status0.getCode());

        if (StringUtils.isNotBlank(MapUtils.getString(param, "name"))) {
            criteria.andNameLike("%"+MapUtils.getString(param, "name")+"%");
        }
        if (StringUtils.isNotBlank(MapUtils.getString(param, "phone"))) {
            criteria.andPhoneLike("%"+MapUtils.getString(param, "phone")+"%");
        }
        if (MapUtils.getInteger(param, "status") != null) {
            criteria.andStatusEqualTo(MapUtils.getInteger(param, "status"));
        }
        example.setOrderByClause("update_time desc");
        return userMapper.selectByExample(example);
    }

    /**
     * 生成token
     * @param user 用户
     * @return
     * @throws Exception
     */
    public String token(BsUser user) throws Exception {
        // token 生成格式：账户id
        return AESEncodeUtil.aesEncrypt(user.getId().toString(), "ydQcF894xdcKQKfc8SEZdZrnSxzMckjZ");
    }

    @Override
    public BsUser register(String phone, String password,Map<String, Object> other) {
        // 查询手机号
        if (getUser(phone) != null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "用户手机号已存在，请更换");
        }
        BsUser user = new BsUser();
        user.setPhone(phone);
        user.setName("嗨用户");
        user.setPassword(password);
        user.setIntegral(0L);
        user.setWxMaOpenid(MapUtils.getString(other, "maOpenId"));
        user.setWxMpOpenid(MapUtils.getString(other, "mpOpenId"));
        user.setStatus(UserStatusEnum.status1.getCode());
        editData(user);
        return user;
    }

    @Override
    public BsUser register(String outsideOpenid, Map<String, Object> other) {
        // 查询手机号
        BsUser user = new BsUser();
        user.setOutsideOpenid(outsideOpenid);
        user.setName("嗨用户");
        user.setIntegral(0L);
        user.setWxMaOpenid(MapUtils.getString(other, "maOpenId"));
        user.setWxMpOpenid(MapUtils.getString(other, "mpOpenId"));
        user.setStatus(UserStatusEnum.status1.getCode());
        editData(user);
        return user;
    }

    @Override
    public SessionObject login(UserLoginPlatform platform, UserLoginType loginType, String phone, String password, Map<String, Object> other) throws Exception {
        // 查询用户
        BsUser user = getUser(phone);
        if (user == null) {
            // 查询用户
            user = getUserByMaOpenId(other.get("maOpenId").toString());
            if (user == null) {
                user = register(phone, password, other);
            }
            user.setPhone(phone);
            editData(user);
        }

        // 缓存
        UserSessionObject session = new UserSessionObject();
        session.setUser(user);

        // 查询汇联通工会卡
        List<BsUserCard> hltCardList = userCardService.getCardList(user.getId(), UserCardTypeEnum.type1);
        if (hltCardList.isEmpty()) {
            session.setHltCardBind(false);
        } else {
            session.setHltCardBind(true);
            session.setHltCard(hltCardList.get(0));
        }
        SessionObject sessionObject = new SessionObject(token(user), session);
        userCenter.save(sessionObject);
        // 异步记录登录信息
        userLoginLogService.asyncCreateLog(platform, loginType, user, (HttpServletRequest) RequestContextHolder.getRequestAttributes().resolveReference(RequestAttributes.REFERENCE_REQUEST));
        return sessionObject;
    }

    @Override
    public SessionObject login(UserLoginPlatform platform, UserLoginType loginType,  String outsideOpenid, Map<String, Object> other) throws Exception {
        BsUser user = getUserByOutsideOpenid(outsideOpenid);
        if (user == null  ) {
            user = register(outsideOpenid, other);
        }

        // 缓存
        UserSessionObject session = new UserSessionObject();
        session.setUser(user);

        // 查询汇联通工会卡
        List<BsUserCard> hltCardList = userCardService.getCardList(user.getId(), UserCardTypeEnum.type1);
        if (hltCardList.isEmpty()) {
            session.setHltCardBind(false);
        } else {
            session.setHltCardBind(true);
            session.setHltCard(hltCardList.get(0));
        }

        SessionObject sessionObject = new SessionObject(token(user), session);
        userCenter.save(sessionObject);
        // 异步记录登录信息
        userLoginLogService.asyncCreateLog(platform, loginType, user, (HttpServletRequest) RequestContextHolder.getRequestAttributes().resolveReference(RequestAttributes.REFERENCE_REQUEST));
        return sessionObject;
    }

    @Override
    public void loginOut(String token) {
        userCenter.remove(token);
    }

    @Override
    public SessionObject updateSession(Long userId) {
        // 查询用户
        BsUser user = getUser(userId);
        if (user == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的用户");
        }
        // 缓存
        UserSessionObject session = new UserSessionObject();
        session.setUser(user);
        // 查询汇联通工会卡
        List<BsUserCard> hltCardList = userCardService.getCardList(user.getId(), UserCardTypeEnum.type1);
        if (hltCardList.isEmpty()) {
            session.setHltCardBind(false);
        } else {
            session.setHltCardBind(true);
            session.setHltCard(hltCardList.get(0));
        }
        try {
            // 重新缓存
            SessionObject newSession = new SessionObject(token(user), session);
            userCenter.save(newSession);
            return newSession;
        } catch (Exception e) {
            return null;
        }
    }


}
