package cn.iocoder.yudao.module.wechat.service.impl;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.common.PromotionEnum;
import cn.iocoder.yudao.common.SystemEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.staff.service.CompanyStaffService;
import cn.iocoder.yudao.module.wechat.service.WechatService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.service.auth.AdminAuthService;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import cn.iocoder.yudao.util.WeChatLoginUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.LOCKED;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

/**
 * @Author vinjor-m
 * @Description 微信模块服务层
 **/
@Service
public class WechatServiceImpl implements WechatService {
    @Autowired
    private WeChatLoginUtil weChatLoginUtil;
    @Autowired
    private AdminUserApi adminUserApi;
    @Resource
    private AdminAuthService loginService;
    @Resource
    private AdminUserService userService;
    @Resource
    private PasswordEncoder passwordEncoder;
    @Autowired
    private CompanyStaffService companyStaffService;
    /**
     * 微信自动登录
     *
     * @param code 参数
     * @return java.lang.String
     * @author vinjor-M
     * @date 23:53 2024/9/23
     **/
    @Override
    public CommonResult<?> loginByOpenId(String code) {
        try {
            //当前登录用户的openId
            Map<String,String> authMap = getWeChatOpenId(code);
            String openId = authMap.getOrDefault("openId",null);
            //默认租户180，查是否有user表数据
            AdminUserRespDTO userRespDTO = adminUserApi.getUserByOpenId(openId,null);
            if(null==userRespDTO){
                //未找到用户，去注册
                return CommonResult.success(openId);
            }else{
                //找到用户，登录并返回
                return success(loginService.wxLoginByUserId(userRespDTO.getId(),userRespDTO.getUsername()));
            }
        }catch (Exception e){
            e.printStackTrace();
            return CommonResult.error(LOCKED.getCode(),e.getMessage());
        }
    }

    /**
     * 获取openId
     * @author vinjor-M 
     * @date 23:56 2024/9/23 
     * @param code （静默/非静默）授权拿到的code
     * @return java.util.Map<java.lang.String,java.lang.String>
    **/
    private Map<String,String> getWeChatOpenId(String code) throws Exception {
        Map<String,String> rtnMap = new HashMap<>(2);
        try {
            //code为空为没有获取到code
            if (StringUtils.isNotBlank(code)) {
                JSONObject tokenJson = weChatLoginUtil.getTokenJson(code);
                //获取到tokenJson后，解析tokenJson获取其openId
                if (null != tokenJson && tokenJson.containsKey("openid")) {
                    rtnMap.put("openId",tokenJson.getStr("openid"));
                    rtnMap.put("token",tokenJson.getStr("access_token"));
                }else{
                    throw new Exception("code过期");
                }
            }else{
                throw new Exception("没有code");
            }
            return rtnMap;
        }  catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    /**
     * 微信授权登录-未注册自动注册，已登录的返回用户信息-
     * --目前维修系统使用，后续客户信息整合可以复用
     *
     * @param sysCode       系统标识
     * @param decryptResult 微信授权解密密文
     * @param openId        微信openId
     * @param inviteId      邀请者code
     * @return cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO
     * @author vinjor-M
     * @date 15:14 2024/10/9
     **/
    @Override
    public AdminUserDO wechatLogin(String sysCode, String decryptResult, String openId, String inviteId) {
        //字符串转json
        JSONObject jsonObject = JSONUtil.parseObj(decryptResult);
        String phoneNumber =  jsonObject.getStr("phoneNumber");
        //根据手机号判断数据库中是否有该用户
        AdminUserDO wxUser = userService.getUserByMobileWithoutTenant(phoneNumber);
        //如果查不到，则新增，查到了，则更新
        UserSaveReqVO user = new UserSaveReqVO();
        if (null == wxUser) {
            // 直接新注册一个账号
            user.setUsername(phoneNumber);
            user.setNickname(phoneNumber);
            user.setMobile(phoneNumber);
            user.setPassword(passwordEncoder.encode("123456"));
            //TODO 客户后期没有租户ID
            user.setTenantId(180L);
            user.setDeptId(100L);
        }else {
            //更新
            user.setId(wxUser.getId());
        }
        String dataFrom = "";
        //设置微信openId
        if(SystemEnum.REPAIR.getCode().equals(sysCode)){
            //维修业务系统
            user.setRepairOpenId(openId);
            dataFrom = SystemEnum.REPAIR.getDataFrom();
        }else if(SystemEnum.INSPECTION.getCode().equals(sysCode)){
            //检测业务系统
            dataFrom = SystemEnum.INSPECTION.getDataFrom();
        }else if(SystemEnum.SCHOOL.getCode().equals(sysCode)){
            //驾校业务系统
            dataFrom = SystemEnum.SCHOOL.getDataFrom();
        }else if(SystemEnum.RESCUE.getCode().equals(sysCode)){
            //救援业务系统
            dataFrom = SystemEnum.RESCUE.getDataFrom();
        }else if(SystemEnum.INSURE.getCode().equals(sysCode)){
            //保险业务系统
            dataFrom = SystemEnum.INSURE.getDataFrom();
        }else {
            //默认维修业务
            user.setRepairOpenId(openId);
            dataFrom = SystemEnum.REPAIR.getDataFrom();
        }
        if(null!=user.getId()){
            //更新
            userService.updateUser(user);
        }else{
            //插入
            Long uid = userService.createUser(user);
            wxUser = new AdminUserDO();
            wxUser.setId(uid);
            wxUser.setUsername(user.getUsername());
            wxUser.setNickname(user.getNickname());
        }
        /*如果携带了邀请码，需要插入邀请记录并自动复制用户信息到邀请者的租户下 */
        if(!StringUtils.isEmpty(inviteId)){
            //邀请注册，自动注册客户信息
            companyStaffService.createPromotion(dataFrom,inviteId,wxUser, PromotionEnum.WeChat.getCode(), new Date());
        }
        return wxUser;
    }
}
