package com.sien.common.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sien.common.entity.AppUser;
import com.sien.common.param.app.AppSmsRegisterParam;
import com.sien.common.param.app.AppUserInfoParam;
import com.sien.common.service.AppSmsService;
import com.sien.common.service.AppUserApiService;
import com.sien.common.service.AppUserService;
import com.sien.common.vo.AppUserQueryVo;
import com.sien.common.vo.app.LoginAppUserTokenVo;
import io.geekidea.springbootplus.config.properties.WxMpProperties;
import io.geekidea.springbootplus.framework.common.api.ApiCode;
import io.geekidea.springbootplus.framework.common.api.ApiResult;
import io.geekidea.springbootplus.framework.shiro.jwt.JwtToken;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class AppUserApiServiceImpl implements AppUserApiService {

    @Autowired
    private AppSmsService appSmsService;
    @Autowired
    private AppUserService appUserService;
//    @Autowired
//    private WxMpService wxMpService;

    @Autowired
    private WxMpProperties properties;

    private WxMpService getWxMpService() {
        // 代码里 getConfigs()处报错的同学，请注意仔细阅读项目说明，你的IDE需要引入lombok插件！！！！
        final List<WxMpProperties.MpConfig> configs = this.properties.getConfigs();
        if (configs == null) {
            throw new RuntimeException("添加下相关配置，注意别配错了！");
        }
        WxMpService service = new WxMpServiceImpl();
        service.setMultiConfigStorages(configs
                .stream().map(a -> {
                    WxMpDefaultConfigImpl configStorage;
//
                    configStorage = new WxMpDefaultConfigImpl();
                    configStorage.setAppId(a.getAppId());
                    configStorage.setSecret(a.getSecret());
                    configStorage.setToken(a.getToken());
                    configStorage.setAesKey(a.getAesKey());
                    return configStorage;
                }).collect(Collectors.toMap(WxMpDefaultConfigImpl::getAppId, a -> a, (o, n) -> o)));
        return service;
    }

    @Override
    public ApiResult<Boolean> updatePhone(String phoneArea, String phone, String code, String codeNew) throws Exception {
        JwtToken jwtToken = (JwtToken) SecurityUtils.getSubject().getPrincipal();

        AppUserQueryVo appUserById = appUserService.getAppUserById(jwtToken.getUserId());

        // 校验旧手机验证码
        boolean equalsRegisterCode = appSmsService.equalsUpdatePhoneCodeOld(appUserById.getPhoneArea(), appUserById.getPhone(), code);
        if (!equalsRegisterCode) {
            return ApiResult.fail(ApiCode.SMS_CODE_ERROR);
        }

        // 校验新手机验证码
        boolean equalsRegisterCodeNew = appSmsService.equalsUpdatePhoneCodeNew(phoneArea, phone, codeNew);
        if (!equalsRegisterCodeNew) {
            return ApiResult.fail(ApiCode.SMS_CODE_ERROR_NEW);
        }

        // 删除已使用的旧手机验证码
        appSmsService.deleteUpdatePhoneCode(appUserById.getPhoneArea(), appUserById.getPhone());
        // 删除已使用的新手机验证码
        appSmsService.deleteUpdatePhoneCodeNew(phoneArea, phone);

        // 判断手机号是否已经注册
        AppUser one = appUserService.getOne(new QueryWrapper<AppUser>().lambda()
                .eq(AppUser::getPhoneArea, phoneArea)
                .eq(AppUser::getPhone, phone));
        if (one != null) {
            return ApiResult.fail(ApiCode.BUSINESS_EXCEPTION);
        }

        AppUser appUser = new AppUser();
        appUser.setPhoneArea(phoneArea);
        appUser.setPhone(phone);
        appUser.setId(jwtToken.getUserId());

        boolean b = appUserService.updateById(appUser);
        if (b) {
            return ApiResult.ok();
        }
        return ApiResult.fail();
    }

    @Override
    public AppUser getUserInfo(Long userId) {
        return appUserService.getOne(new QueryWrapper<AppUser>().lambda().eq(AppUser::getId, userId));
    }

    @Override
    public ApiResult<List<AppUser>> getAppUserList(Set<Long> uids) {
        return ApiResult.ok(appUserService.list(new QueryWrapper<AppUser>().lambda().in(AppUser::getId, uids)));
    }

    @Override
    public ApiResult<LoginAppUserTokenVo> register(AppSmsRegisterParam loginParam, String language) throws Exception {
        // 校验验证码
        boolean equalsRegisterCode = appSmsService.equalsRegisterCode(loginParam.getPhoneArea(), loginParam.getPhone(), loginParam.getSmsCode());
        if (!equalsRegisterCode) {
            return ApiResult.fail(ApiCode.SMS_CODE_REGIST_ERROR, new LoginAppUserTokenVo());
        }
        // 删除已使用的验证码
        appSmsService.deleteRegisterCode(loginParam.getPhoneArea(), loginParam.getPhone());
        // 判断是否已经注册
        if (appUserService.hasUserByPhoneNumer(loginParam.getPhoneArea(), loginParam.getPhone())) {
            // 如果已经注册直接走登陆的代码
            return appUserService.login(loginParam, language, true);
        }

        // 没注册则保存到数据库
        AppUser appUserByOpenId = appUserService.getOne(new QueryWrapper<AppUser>().lambda().eq(AppUser::getWechatOpenId, loginParam.getOpenId()));
        appUserByOpenId.setPhoneArea(loginParam.getPhoneArea());
        appUserByOpenId.setPhone(loginParam.getPhone());
        appUserByOpenId.setUsername(loginParam.getUserName());

        boolean isDbOk = appUserService.updateById(appUserByOpenId);
        if (!isDbOk) {
            return ApiResult.fail(ApiCode.SPRING_BOOT_PLUS_EXCEPTION, new LoginAppUserTokenVo());
        }

        // 走登陆的代码
        return appUserService.login(loginParam, language, false);
    }

//    @Override
//    public ApiResult<LoginAppUserTokenVo> login(AppSmsRegisterParam loginParam, String language) throws Exception {
//        return null;
//    }

    @Override
    public boolean updateAppUser(AppUserInfoParam appUserInfoParam) throws Exception {

        AppUser appUser = new AppUser();
        BeanUtils.copyProperties(appUserInfoParam, appUser);

        JwtToken jwtToken = (JwtToken) SecurityUtils.getSubject().getPrincipal();

        appUser.setId(jwtToken.getUserId());

        return appUserService.updateAppUser(appUser);
    }

}
