package com.yiqi.app.service.impl;

import java.util.Date;
import java.util.List;

import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yiqi.common.exception.ServiceException;
import com.google.gson.Gson;
import com.yiqi.app.domain.AppOrgUser;
import com.yiqi.app.domain.dto.weapp.WeAppWxLoginDTO;
import com.yiqi.app.domain.vo.AppUserInfoVO;
import com.yiqi.app.domain.vo.AppUserLoginVO;
import com.yiqi.app.service.IAppOrgUserService;
import com.yiqi.app.service.IWeAppTokenService;
import com.yiqi.common.config.CompositeWxMaService;
import com.yiqi.common.core.domain.AuthInfoDO;
import com.yiqi.common.core.domain.R;
import com.yiqi.common.enums.PlatformType;
import com.yiqi.common.enums.StatusType;
import com.yiqi.common.enums.SysBoolType;
import com.yiqi.common.enums.UserStatus;
import com.yiqi.common.utils.DateUtils;
import com.yiqi.common.utils.SecurityUtils;
import com.yiqi.common.utils.StringUtils;
import com.yiqi.recharge.mapper.RechargePasswordCardMapper;
import com.yiqi.system.domain.SysSessionRecord;
import com.yiqi.system.service.ISysSessionRecordService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yiqi.app.mapper.AppUserMapper;
import com.yiqi.app.domain.AppUser;
import com.yiqi.app.service.IAppUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

/**
 * 用户Service业务层处理
 *
 * @author ruoyi
 * @date 2023-10-03
 */
@Service
public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> implements IAppUserService {

    @Autowired
    IAppOrgUserService appOrgUserService;
    @Autowired
    private CompositeWxMaService compositeWxMaService;
    @Autowired
    private IWeAppTokenService weAppTokenService;
    @Autowired
    private ISysSessionRecordService sysSessionRecordService;
    @Autowired
    private RechargePasswordCardMapper rechargePasswordCardMapper;

    @Override
    public R<AppUserLoginVO> wxLogin(WeAppWxLoginDTO weAppWxLoginDTO) throws Exception {
        boolean isRegist = false;
        System.out.println("wxLoginDTO:" + new Gson().toJson(weAppWxLoginDTO));
        WxMaJscode2SessionResult result = compositeWxMaService.get().getUserService().getSessionInfo(weAppWxLoginDTO.getJsCode());
        // 解密
        WxMaPhoneNumberInfo phoneNoInfo = null;
        //优先使用新版的获取手机号方式

        if (StringUtils.isNotEmpty(weAppWxLoginDTO.getPhoneCode())) {
            phoneNoInfo = compositeWxMaService.get().getUserService().getNewPhoneNoInfo(weAppWxLoginDTO.getPhoneCode());
        } else {
            phoneNoInfo = compositeWxMaService.get().getUserService().getPhoneNoInfo(result.getSessionKey()
                    , weAppWxLoginDTO.getEncryptedData(), weAppWxLoginDTO.getIv());
        }
        AppUser user = getOne(new QueryWrapper<AppUser>().lambda().eq(AppUser::getPhoneNumber, phoneNoInfo.getPurePhoneNumber()), false);
        if (user == null) {//没有账号，直接创建
            isRegist = true;
            user = new AppUser();
            user.setPhoneNumber(phoneNoInfo.getPurePhoneNumber());
            user.setNickName("用户-" + RandomUtil.randomNumbers(8));
            user.setStatus(UserStatus.OK.getCode());
            user.setSex("0");
            user.setLevel(1);
            user.setUnionId(result.getUnionid());
            user.setWxOpenId(result.getOpenid());
            user.setCreateTime(DateUtils.getNowDate());
            save(user);

            //清除之前关联的unionId账户
            LambdaUpdateWrapper<AppUser> userLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            userLambdaUpdateWrapper.set(AppUser::getUnionId, "");
            userLambdaUpdateWrapper.set(AppUser::getWxOpenId, "");
            userLambdaUpdateWrapper.eq(AppUser::getUnionId, user.getUnionId());
            userLambdaUpdateWrapper.ne(AppUser::getPhoneNumber, user.getPhoneNumber());
            update(userLambdaUpdateWrapper);
        } else if (StringUtils.isEmpty(user.getUnionId()) || !user.getUnionId().equals(result.getUnionid())) {
            user.setUnionId(result.getUnionid());
            user.setWxOpenId(result.getOpenid());
            updateById(user);
            //清除之前关联的unionId账户
            LambdaUpdateWrapper<AppUser> userLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            userLambdaUpdateWrapper.set(AppUser::getUnionId, "");
            userLambdaUpdateWrapper.set(AppUser::getWxOpenId, "");
            userLambdaUpdateWrapper.eq(AppUser::getUnionId, user.getUnionId());
            userLambdaUpdateWrapper.ne(AppUser::getPhoneNumber, user.getPhoneNumber());
            update(userLambdaUpdateWrapper);
        }
        if (user.getStatus().equals(StatusType.DELETED.getCode())) {
            throw new ServiceException("当前账号已被禁用，如需解封请联系平台客服人员");
        }
        //创建token
        String token = weAppTokenService.createToken(new AuthInfoDO(user));

        //持久化存储token
        SysSessionRecord sysSessionRecord = sysSessionRecordService.getOne(new QueryWrapper<SysSessionRecord>()
                .lambda().eq(SysSessionRecord::getAppUserId, user.getId())
                .eq(SysSessionRecord::getPlatformType, PlatformType.USER.getCode())
                .eq(SysSessionRecord::getSessionPlatformType, weAppWxLoginDTO.getPlatform()));
        if (sysSessionRecord == null) {
            sysSessionRecord = new SysSessionRecord();
            sysSessionRecord.setAppUserId(user.getId());
            sysSessionRecord.setSessionPlatformType(weAppWxLoginDTO.getPlatform());
            sysSessionRecord.setPlatformType(PlatformType.USER.getCode());
            sysSessionRecord.setUnionId(result.getUnionid());
            sysSessionRecord.setToken(token);
        } else {//清楚之前的缓存记录
            weAppTokenService.delLoginUser(sysSessionRecord.getToken());
            sysSessionRecord.setToken(token);
        }
        sysSessionRecordService.saveOrUpdate(sysSessionRecord);

        AppUserLoginVO appUserLoginVO = new AppUserLoginVO();
        BeanUtils.copyProperties(user, appUserLoginVO);
        appUserLoginVO.setToken(token);
        return R.ok(appUserLoginVO);
    }

    @Override
    public AppUserInfoVO getAppUserInfoById(Long appUserId) {
        return baseMapper.getAppUserInfoById(appUserId);
    }

    @Override
    public List<AppUserInfoVO> getAppUserInfoByIds(List<Long> appUserIds) {
        return baseMapper.getAppUserInfoByIds(appUserIds);
    }

    /**
     * 查询用户
     *
     * @param id 用户主键
     * @return 用户
     */
    @Override
    public AppUser selectAppUserById(Long id) {
        return baseMapper.selectAppUserById(id);
    }

    /**
     * 查询用户列表
     *
     * @param appUser 用户
     * @return 用户
     */
    @Override
    public List<AppUser> selectAppUserList(AppUser appUser) {
        return baseMapper.selectAppUserList(appUser);
    }

    /**
     * 新增用户
     *
     * @param appUser 用户
     * @return 结果
     */
    @Override
    public int insertAppUser(AppUser appUser) {
        AppUser user = baseMapper.selectOne(new QueryWrapper<AppUser>().lambda().eq(AppUser::getPhoneNumber, appUser.getPhoneNumber()));
        // 存在客户，绑定门店关系
        if (user != null) {
            appOrgUserService.insertAppOrgUserByAppUser(user);
            return 1;
        }
        // 不存在客户， 新建客户，然后绑定关系
        appUser.setCreateTime(DateUtils.getNowDate());
        if (StrUtil.isEmpty(appUser.getIsUsePayPassword())) {
            appUser.setIsUsePayPassword(SysBoolType.NO.getCode());
        }
        this.save(appUser);
        appOrgUserService.insertAppOrgUserByAppUser(appUser);
        return 1;
    }

    /**
     * 修改用户
     *
     * @param appUser 用户
     * @return 结果
     */
    @Override
    public int updateAppUser(AppUser appUser) {
        return baseMapper.updateAppUser(appUser);
    }

    /**
     * 批量删除用户
     *
     * @param ids 需要删除的用户主键
     * @return 结果
     */
    @Override
    public int deleteAppUserByIds(Long[] ids) {
        return baseMapper.deleteAppUserByIds(ids);
    }

    /**
     * 删除用户信息
     *
     * @param id 用户主键
     * @return 结果
     */
    @Override
    public int deleteAppUserById(Long id) {
        return baseMapper.deleteAppUserById(id);
    }

    /**
     * 修改用户状态
     *
     * @param appUser 用户
     * @return 结果
     */
    @Override
    public int updateAppUserStatus(AppUser appUser) {
        return baseMapper.updateAppUser(appUser);
    }

    @Override
    public Boolean checkUserIsMember(Long appUserId) {
        Long count = rechargePasswordCardMapper.getCountyByAppUserId(appUserId);
        return count > 0;
    }

    @Override
    public Boolean checkUserIsNewUser(Long appUserId) {
        AppUser user = baseMapper.selectAppUserById(appUserId);
        //注册日期在一周内的用户都是新用户
        if (DateUtil.between(user.getCreateTime(), new Date(), DateUnit.DAY, true) <= 7) {
            return true;
        }
        return false;
    }

}
