package com.xunwang.ucenter.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.xunwang.servicebase.utils.JwtUtils;
import com.xunwang.servicebase.utils.RedisIdWorker;
import com.xunwang.servicebase.utils.ResultCode;
import com.xunwang.servicebase.exception.XunwangException;
import com.xunwang.ucenter.entity.MpOpenidUid;
import com.xunwang.ucenter.feign.MsgFeign;
import com.xunwang.ucenter.mapper.MiniProgramOpenidUidMapper;
import com.xunwang.ucenter.service.MiniProgramOpenidUidService;
import com.xunwang.ucenter.utils.HttpClientUtils;
import com.xunwang.ucenter.utils.LocationUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

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

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Long
 * @since 2022-11-09
 */
@Service
@Slf4j
public class MiniProgramOpenidUidServiceImpl extends ServiceImpl<MiniProgramOpenidUidMapper, MpOpenidUid> implements MiniProgramOpenidUidService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private RedisIdWorker redisIdWorker;

    @Resource
    private MsgFeign msgFeign;

    /**
     * 获取用户openid，unionid等
     * @param appid
     * @param secret
     * @param code
     * @param grant_type
     * @return
     */
    @Override
    public Map<String, Object> getOpenId(HttpServletRequest request, String appid, String secret, String code, String grant_type,String recoUID) throws Exception {
        // 调用微信登录接口
        String baseCode2SessionUrl = "https://api.weixin.qq.com/sns/jscode2session" + "?appid=%s" + "&secret=%s" + "&js_code=%s" + "&grant_type=%s";
        String code2SessionUrl = String.format(baseCode2SessionUrl, appid, secret, code, grant_type);
        String result = HttpClientUtils.get(code2SessionUrl);

        // 解析json字符串
        Gson gson = new Gson();
        HashMap<String, Object> hashMap = gson.fromJson(result, HashMap.class);

        // 获取openid、unionid等
        String openid = (String) hashMap.get("openid");
        String unionid = (String) hashMap.get("unionid");

        // 获取ip地址
        String ip = getIp(request);
        String city = LocationUtils.getRegionFromIp(ip);

        MpOpenidUid user = baseMapper.selectOne(new QueryWrapper<MpOpenidUid>().eq("openid", openid));
        String alias = "";
        String formatUid = "";
        String lastLogin = "";
        String avatar = "";
        String tureRecoUID = "";
        if (user == null) {
            // 新用户注册
            user = new MpOpenidUid();
            long uid = redisIdWorker.nextId("uid");
            formatUid = String.format("%08x", uid);
            String prefix = "ID_";
            alias = prefix + formatUid;
            avatar = "http://125.71.216.35:9001/education/avatar.png";

            user.setOpenid(openid).setUnionid(unionid).setAlias(alias).setAvatar(avatar).setCity(city).setUid(formatUid).setRecommendUid(recoUID);
            baseMapper.insert(user);
            lastLogin = user.getLastLoginDatetime();
            tureRecoUID = recoUID;

        } else {
            // 老用户登录
            alias = user.getAlias();
            formatUid = user.getUid();
            lastLogin = user.getLastLoginDatetime();
            avatar = user.getAvatar();

            user.setLastLoginDatetime(null).setCity(city);
            baseMapper.updateById(user);
            tureRecoUID = user.getRecommendUid();
        }

        // 将用户信息生成token字符串
        String token = JwtUtils.getJwtToken(user.getUid(), openid,tureRecoUID);

        int count = msgFeign.queryUnreadCount(formatUid);

        // 返回信息
        HashMap<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("alias", alias);
        map.put("city", city);
        map.put("login", lastLogin);
        map.put("uid", formatUid);
        map.put("count", count);
        map.put("avatar", avatar);
        map.put("isAdmin", user.getIsAdmin());

        return map;
    }

    /**
     * 修改微信昵称
     * @param uid
     * @param alias
     * @return
     */
    @Override
    public void editAlias(String uid, String alias, String avatar) {
        MpOpenidUid mpOpenidUid = new MpOpenidUid();
        mpOpenidUid.setAlias(alias);
        mpOpenidUid.setUid(uid);
        mpOpenidUid.setAvatar(avatar);
        int count = baseMapper.updateById(mpOpenidUid);
        if (count != 1) {
            throw new XunwangException(ResultCode.ERROR, "更新昵称失败！");
        }
    }

    /**
     * 获取用户手机号
     * @param uid
     * @param code
     * @throws Exception
     */
    @Override
    public String getUserPhone(String uid, String code) throws Exception {
        // 调用微信获取电话接口
        String basePhoneUrl = "https://api.weixin.qq.com/wxa/business/getuserphonenumber" + "?access_token=%s";
        if (!redisTemplate.hasKey("access_token")) {
            throw new XunwangException(ResultCode.ERROR, "access_token过期！");
        }
        String access_token = (String) redisTemplate.opsForValue().get("access_token");
        String formatPhoneUrl = String.format(basePhoneUrl, access_token);

        // 传入请求体
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("code", code);
        String result = HttpClientUtils.postParameters(formatPhoneUrl, jsonObject.toString());

        // 解析结果
        Gson gson = new Gson();
        HashMap<String, Object> hashMap = gson.fromJson(result, HashMap.class);
        Map phone_info = (Map)hashMap.get("phone_info");

        String phone = "";
        try {
            phone = phone_info.get("phoneNumber").toString();
        } catch (Exception e) {
            log.error("手机号获取失败", e);
        }

        // 查询数据库
        QueryWrapper<MpOpenidUid> queryWrapper = new QueryWrapper<MpOpenidUid>();
        queryWrapper.eq("uid", uid);
        MpOpenidUid mpOpenidUid = baseMapper.selectOne(queryWrapper);
        String uidPhone = mpOpenidUid.getPhone();
        if (uidPhone == null) {
            uidPhone = "";
        }

        if (phone != null) {
            // 更新
            if (!uidPhone.equals(phone)) {
                mpOpenidUid.setPhone(phone);
                baseMapper.update(mpOpenidUid, queryWrapper);
            }
        } else {
            phone = uidPhone;
        }
        return phone;
    }

    /**
     * 获取当前请求的IP地址
     * @param request
     * @return
     */
    private String getIp(HttpServletRequest request) {
        String ip = "";
        if (request.getHeader("x-forwarded-for") == null) {
            ip = request.getRemoteAddr();
        } else {
            ip = request.getHeader("x-forwarded-for");
        }
        return ip;
    }

    /**
     * 获取 推荐人uid 注册的数量
     * @param recoUID
     * @return int
     */
    @Override
    public int getShareCount(String recoUID) {
        return  baseMapper.selectCount(new QueryWrapper<MpOpenidUid>().eq("recommend_uid", recoUID));
    }

    /**
     * TODO
     *
     * @Description 根据uid, 取 认证通过 教员 条数
     * @Author Paul  Email:8203193@qq.com
     * @Version 1.0
     * @Date 2023/6/13 13:15
     *
     */
    @Override
    public int getShareTeacherCount(String recoUID) {
        return baseMapper.selectShareTeacherCount(recoUID);
    }

//    /**
//     * 获取 推荐人uid 对应的已发布的有效的（未下架） 课程与需求 之和
//     * @param recoUID
//     * @return int
//     */
//    @Override
//    public int getSharePublishCount(String recoUID) {
//        List<Map<String, Object>> mapList = baseMapper.selectMaps(new QueryWrapper<MpOpenidUid>().select("uid").eq("recommend_uid", recoUID));
//        int count = 0;
//
//        for (Map<String, Object> map : mapList) {
//            for (String s : map.keySet()) {
//                count += baseMapper.selectShareCourseCount(map.get(s).toString());
//                count += baseMapper.selectShareNeedCount(map.get(s).toString());
//            }
//        }
//        return count;
//    }

    /**
     * 获取 推荐人uid 对应的 未退款的订单条数
     * @param recoUID
     * @return int
     */
    @Override
    public int getShareOrderCount(String recoUID) {
        return baseMapper.selectShareOrderCount(recoUID);
    }

    /**
     * TODO
     *
     * @Description
     * @Author Paul  Email:8203193@qq.com
     * @Version 1.0
     * @Date 2023/6/12 15:49
     *
     */
    @Override
    public void updateOwnQRcodeUrl(String uid, String qrurl) {
        baseMapper.updateOwnQRcodeUrl(uid,qrurl);
    }

    /**
     * TODO
     *
     * @Description
     * @Author Paul  Email:8203193@qq.com
     * @Version 1.0
     * @Date 2023/6/12 15:49
     *
     */
    @Override
    public String getOwnQRcodeUrl(String uid) {
        return baseMapper.getOwnQRcodeUrl(uid);
    }
}
