package com.zhiqiyun.open.core.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dliyun.AlgorithmType;
import com.dliyun.ClientException;
import com.dliyun.DefaultClient;
import com.dliyun.Response;
import com.google.common.collect.Lists;
import com.zhiqiyun.open.config.RedisKeys;
import com.zhiqiyun.open.core.enmus.AccountType;
import com.zhiqiyun.open.core.enmus.Gender;
import com.zhiqiyun.open.core.enmus.UserState;
import com.zhiqiyun.open.core.mapper.UserBaseInfoMapper;
import com.zhiqiyun.open.core.mapper.UserLoginAccountMapper;
import com.zhiqiyun.open.core.models.user.OauthInfo;
import com.zhiqiyun.open.core.models.user.UserBaseInfo;
import com.zhiqiyun.open.core.models.user.UserLoginAccount;
import com.zhiqiyun.open.core.service.UnifiedLoginService;
import com.zhiqiyun.open.utils.DateUtil;
import com.zhiqiyun.open.utils.ServletContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import us.codecraft.webmagic.utils.IPUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class OauthServiceRedisImpl extends BaseOauthService {

    @Resource
    private RedisTemplate<String, OauthInfo> redisTemplate;

    @Resource
    private UserBaseInfoMapper userBaseInfoMapper;

    @Resource
    private UnifiedLoginService unifiedLoginService;

    @Resource
    private UserLoginAccountMapper userLoginAccountMapper;

    @Override
    public void setAuth(String accessToken, OauthInfo oauthInfo) {
        try {
            String redisKey = String.format(RedisKeys.OAUTH, accessToken);
            this.redisTemplate.boundValueOps(redisKey).set(oauthInfo, 30, TimeUnit.DAYS);
        } catch (Exception e) {
            log.error("save oauth error", e);
        }

    }

    @Override
    public OauthInfo getAuth(String accessToken) {
        try {
            if (StringUtils.isBlank(accessToken)) {
                return null;
            }
            String redisKey = String.format(RedisKeys.OAUTH, accessToken);

            BoundValueOperations<String, OauthInfo> boundValueOperations = this.redisTemplate.boundValueOps(redisKey);
            boundValueOperations.expire(30, TimeUnit.DAYS);
            OauthInfo oauthInfo = boundValueOperations.get();
            if (oauthInfo != null && accessToken.equals(oauthInfo.getAccessToken())) {
                return oauthInfo;
            }

            //同步畅行账户体系数据
//            return loadUnified(accessToken, oauthInfo);
        } catch (Exception e) {
            log.error("get oauth error", e);
        }
        return null;
    }

    /**
     * 同步畅行用户体系
     *
     * @param accessToken accessToken
     * @param oauthInfo   oauthInfo
     * @return
     * @throws ClientException
     */
    private OauthInfo loadUnified(String accessToken, OauthInfo oauthInfo) throws ClientException {
        Response<JSONObject> response = unifiedLoginService.loginAccessToken(accessToken);
        if (response.isSuccessful()) {
            JSONObject jsonObject = response.getBody();
            System.out.println(jsonObject.toJSONString());
            Long unifiedId = jsonObject.getLong("userId");

            QueryWrapper<UserBaseInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("unified_id", unifiedId);
            UserBaseInfo userBaseInfo = userBaseInfoMapper.selectOne(queryWrapper);
            if (userBaseInfo != null) {
                List<String> listAuthorities = userBaseInfoMapper.findUserAuthorities(userBaseInfo.getId());

                oauthInfo = new OauthInfo().setId(userBaseInfo.getId()).setAccessToken(accessToken).setNickName(userBaseInfo.getNickName()).setAvatar(userBaseInfo.getAvatar()).setLoginTime(DateUtil.current()).setGender(userBaseInfo.getGender()).setAuthorities(listAuthorities);
                setAuth(accessToken, oauthInfo);
            } else {
                List<UserLoginAccount> loginAccounts = new ArrayList<>();
                JSONObject userVO = jsonObject.getJSONObject("userVO");
                String phone = userVO.getString("phone");
                String email = userVO.getString("email");
                if (StringUtils.isNotBlank(email)) {
                    loginAccounts.add(new UserLoginAccount(email, AccountType.email));
                }
                if (StringUtils.isNotBlank(phone)) {
                    loginAccounts.add(new UserLoginAccount(phone, AccountType.mp));
                }
                UserBaseInfo baseInfo = new UserBaseInfo();
                baseInfo.setNickName(userVO.getString("name"));
                baseInfo.setGender(Gender.valueOf(userVO.getIntValue("sex")));
                baseInfo.setRegisterIp(ServletContext.getRemoteIPAddress());
                baseInfo.setUnifiedId(userVO.getLong("id"));
                baseInfo.setState(UserState.normal);
                baseInfo.setRegisterTime(new Date());
                baseInfo.setAvatar("");
                userBaseInfoMapper.insert(baseInfo);

                userLoginAccountMapper.deleteByUid(baseInfo.getId());
                for (UserLoginAccount loginAccount : loginAccounts) {
                    loginAccount.setUid(baseInfo.getId());
                    userLoginAccountMapper.insertOrUpdate(loginAccount);
                }
                oauthInfo = new OauthInfo().setId(baseInfo.getId()).setAccessToken(accessToken).setNickName(baseInfo.getNickName()).setAvatar(baseInfo.getAvatar()).setLoginTime(DateUtil.current()).setGender(baseInfo.getGender()).setAuthorities(new ArrayList<>());
                setAuth(accessToken, oauthInfo);
            }
        }
        return oauthInfo;
    }


    @Override
    public void destroy(String accessToken) {
        //销毁登录信息
        String redisKey = String.format(RedisKeys.OAUTH, accessToken);

        this.redisTemplate.delete(redisKey);
    }
}
