package cn.ey.biz.module.system.service.user;

import cn.ey.biz.module.system.api.user.dto.UserSwitchRecordReqDTO;
import cn.ey.biz.module.system.convert.user.UserSwitchRecordConvert;
import cn.ey.biz.module.system.dal.dataobject.user.UserSwitchRecordDO;
import cn.ey.biz.module.system.dal.mapper.user.UserSwitchRecordMapper;
import cn.ey.biz.module.system.dal.redis.switchuser.SwitchUserRedisDAO;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import static cn.ey.biz.common.exception.util.ServiceExceptionUtil.exception;
import static cn.ey.biz.module.system.enums.ErrorCodeConstants.*;

@Slf4j
@Service
public class UserSwitchRecordServiceImpl implements  UserSwitchRecordService {

    @Resource
    private UserSwitchRecordMapper userSwitchRecordMapper;
    @Resource
    private SwitchUserRedisDAO switchUserRedisDAO;

    @Override
    @Transactional
    public void saveSwitchUser(UserSwitchRecordReqDTO userSwitchRecordReqDTO) {
        /*
        示例：
        登录 从 到
        ------情况1----------
        a	 a	 b 都无效
        a	 b 	 a
        ------情况2----------
        a	 a	 b 都有效
        b	 b	 a
        ------情况3----------
        a	 a	 b 失效
        a	 a 	 c 有效
        --------------------
         */
        //判断是否在当前时间范围
        if(!isEffectiveDateEstimate(userSwitchRecordReqDTO.getStartTime(),userSwitchRecordReqDTO.getEndTime())){
            throw exception(SYNC_USERS_SWITCH_DATE);
        }
        UserSwitchRecordDO usrDO = UserSwitchRecordConvert.INSTANCE.convert(userSwitchRecordReqDTO);
        usrDO.setDeleted(false);
        //情况1：如果切换的用户为当前用户，则所有的切换记录为无效
        if(userSwitchRecordReqDTO.getCurrentUserId().equals(userSwitchRecordReqDTO.getToUserId())){
            usrDO.setDeleted(true);//并设为无效，仅做记录
        }
        //当前账号之前切换记录设为无效
        LambdaQueryWrapper<UserSwitchRecordDO> deleteWrapper = Wrappers.lambdaQuery(UserSwitchRecordDO.class)
                .eq(UserSwitchRecordDO::getAppCode, userSwitchRecordReqDTO.getAppCode())
                .eq(UserSwitchRecordDO::getCurrentUserId, userSwitchRecordReqDTO.getCurrentUserId());
        userSwitchRecordMapper.delete(deleteWrapper);
        //存入切换记录
        userSwitchRecordMapper.insert(usrDO);

        if(usrDO.getDeleted()){
            //清除缓存
            switchUserRedisDAO.delete(userSwitchRecordReqDTO.getAppCode(),
                    String.valueOf(userSwitchRecordReqDTO.getCurrentUserId()));
        }else {
            //加入缓存
            switchUserRedisDAO.set(userSwitchRecordReqDTO.getAppCode(),
                    String.valueOf(userSwitchRecordReqDTO.getCurrentUserId()),
                    userSwitchRecordReqDTO.getToUserId()
            );

        }

    }
    @Override
    public Long querySwitchUser(UserSwitchRecordReqDTO userSwitchRecordReqDTO) {
        Long toUserId = switchUserRedisDAO.get(userSwitchRecordReqDTO.getAppCode(),
                String.valueOf(userSwitchRecordReqDTO.getCurrentUserId()));
        if(toUserId!=null){
            return toUserId;
        }
        LambdaQueryWrapper<UserSwitchRecordDO> queryWrapper = Wrappers.lambdaQuery(UserSwitchRecordDO.class)
                .eq(UserSwitchRecordDO::getCurrentUserId, userSwitchRecordReqDTO.getCurrentUserId())
                .eq(UserSwitchRecordDO::getAppCode, userSwitchRecordReqDTO.getAppCode());
        UserSwitchRecordDO userSwitchRecordDO = userSwitchRecordMapper.selectOne(queryWrapper);
        if(userSwitchRecordDO !=null){
            switchUserRedisDAO.set(userSwitchRecordDO.getAppCode(),
                    String.valueOf(userSwitchRecordDO.getCurrentUserId()),
                    userSwitchRecordDO.getToUserId()
                    );
            return userSwitchRecordDO.getToUserId();
        }
        return null;
    }

    @Override
    public void updateSwitchUser(UserSwitchRecordReqDTO userSwitchRecordReqDTO) {
        LambdaQueryWrapper<UserSwitchRecordDO> recordWrapper = Wrappers.lambdaQuery(UserSwitchRecordDO.class)
                .eq(UserSwitchRecordDO::getAppCode, userSwitchRecordReqDTO.getAppCode())
                .eq(UserSwitchRecordDO::getCurrentUserId, userSwitchRecordReqDTO.getCurrentUserId());
        List<UserSwitchRecordDO>  userSwitchRecordDO=userSwitchRecordMapper.selectList(recordWrapper);

        if(CollectionUtil.isNotEmpty(userSwitchRecordDO)){
            for(UserSwitchRecordDO  switchRecord:userSwitchRecordDO){
                switchRecord.setStartTime(userSwitchRecordReqDTO.getStartTime());
                switchRecord.setEndTime(userSwitchRecordReqDTO.getEndTime());
                userSwitchRecordMapper.updateById(switchRecord);
            }
        }
    }

    /**
     * 判断当前时间是否在范围内
     *
     * @param startTime
     * @param endTime
     * @return
     */
    public boolean isEffectiveDateEstimate(Date startTime, Date endTime) {
        if(startTime!=null && endTime!=null){
            return DateUtil.isIn(DateUtil.date(), startTime, endTime);
        }else if(startTime!=null){
            return DateUtil.date().after(startTime);
        }else if(endTime!=null){
            return DateUtil.date().before(endTime);
        }
        return true;
    }

}
