package com.example.demo.module.login;

import com.alibaba.fastjson.JSONObject;
import com.example.demo.common.EmojiTool;
import com.example.demo.common.GlobalConfig;
import com.example.demo.common.GlobalRoot;
import com.example.demo.common.RequestResult;
import com.example.demo.module.iosapi.AppleUtil;
import com.example.demo.module.wxapi.WxApiService;
import com.example.demo.table.UserLogin;
import com.example.demo.table.user.UserInfo;
import org.omg.CORBA.UserException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import pers.jc.sql.SQL;

import java.io.UnsupportedEncodingException;
import java.time.LocalDateTime;
import java.time.ZoneId;

/**
 * 服务-游戏登陆
 */
@Service
public class GameLoginService {
    public static GameLoginService ins;

    //token的过期时间天数
    @Value("${myToken.timeOut}")
    int loginTime_day = 7;

    public GameLoginService() {
        ins = this;
    }

    @Autowired
    GameLoginRepository repository;
    @Autowired
    WxApiService wxApiService;

    public RequestResult login(String username, String password, int appServerIndex) {
        RequestResult requestResult = new RequestResult();
        UserLogin userLogin = repository.getUserLogin(username);
        if (userLogin == null) {
            requestResult.setCode(-1);
            requestResult.setMsg("账号未注册");
//        } else if (userLogin.getServerIndex() != appServerIndex) {
//            requestResult.setCode(-3);
//            requestResult.setMsg("该账号不属于当前服务区");
        } else if (userLogin.getPassword().equals(password)) {
            long timeout = getTokenTimeout(); //System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 7;
            userLogin.setToken_timeout(timeout);
            LoginToken loginToken = LoginToken.parseUserLogin(userLogin, appServerIndex);
            userLogin.setToken(loginToken.getLoginTokenForDatabase());
            repository.updateUserLogin(userLogin);
            requestResult.setData(loginToken.toClientToken());
            requestResult.setMsg("登录成功");
        } else {
            requestResult.setCode(-2);
            requestResult.setMsg("密码错误");
        }
        return requestResult;
    }

    public RequestResult loginByWX(String loginCode, int appServerIndex) throws UnsupportedEncodingException {
        RequestResult requestResult = new RequestResult();
        if (!GlobalConfig.checkServerIndexValid(appServerIndex)) {
            requestResult.setMsg("服务区ID非法");
            requestResult.setFailCode();
            return requestResult;
        }
        JSONObject wxLoginRes = wxApiService.requestAccessToken(loginCode);
        String unionID = wxLoginRes.getString("unionid");
        if (unionID == null || unionID.length() == 0) {
            requestResult.setFailCode();
            requestResult.setMsg("获取unionID失败");
            return requestResult;
        }
        String access_token = wxLoginRes.getString("access_token");
        String openid = wxLoginRes.getString("openid");
        JSONObject wxUserInfoRes = wxApiService.requestUserInfo(access_token, openid);

        //昵称
        String wxNickname = wxUserInfoRes.getString("nickname");
        wxNickname = new String(wxNickname.getBytes("ISO-8859-1"), "UTF-8");
        if (wxNickname == null) wxNickname = "o";
        wxNickname = EmojiTool.replaceEmoji(wxNickname, "o");
        if (wxNickname.length() > 12) wxNickname = wxNickname.substring(0, 12);
        //头像
        String headimgurl = wxUserInfoRes.getString("headimgurl");
        if (headimgurl == null) headimgurl = "";
        final String avatarUrl = headimgurl;
        //性别
        int sex = wxUserInfoRes.getInteger("sex");
        if (sex != 1) sex = 2;

        String username = "wx-" + unionID;
        String password = "wx-unionid";
        boolean needBindPhone;
        UserLogin userLogin = repository.getUserLogin(username);
        if (userLogin == null) {
            needBindPhone = true;
            userLogin = new UserLogin();
            userLogin.setUsername(username);
            userLogin.setPassword(password);
            userLogin.setServerIndex(appServerIndex);
            //用户信息
            UserInfo userInfo = new UserInfo();
            userInfo.setNickname(wxNickname);
            userInfo.setAvatarID(-1);
            userInfo.setAvatarUrl(avatarUrl);
            userInfo.setGender(sex);
            //插入用户信息
            boolean res = repository.insertNewUser(userLogin, userInfo);
            if (!res) {
                requestResult.setFailCode();
                requestResult.setMsg("注册失败");
                return requestResult;
            }
        } else {
            int userId = userLogin.getId();
            needBindPhone = GlobalRoot.db.selectOne(UserInfo.class, new SQL() {{
                WHERE("id = " + PARAM(userId));
            }}).getPhone().equals("");
            final boolean needBindPhoneFinal = needBindPhone;
            final String nickname = wxNickname;
            GlobalRoot.db.update(new SQL() {{
                UPDATE(UserInfo.class);
                SET("avatarUrl = " + PARAM(avatarUrl));
                if (needBindPhoneFinal) {
                    SET("avatarID = " + PARAM(-1));
                    SET("nickname = " + PARAM(nickname));
                }
                WHERE("id = " + PARAM(userId));
            }});
        }
        long timeout = getTokenTimeout();
        userLogin.setToken_timeout(timeout);
        LoginToken loginToken = LoginToken.parseUserLogin(userLogin, appServerIndex);
        userLogin.setToken(loginToken.getLoginTokenForDatabase());
        repository.updateUserLogin(userLogin);
        JSONObject data = new JSONObject();
        data.put("token", loginToken.toClientToken());
        data.put("needBindPhone", needBindPhone);
        requestResult.setData(data);
        requestResult.setMsg("登录成功");
        return requestResult;
    }

    public RequestResult loginByToken(String clientToken, String sceneName, int appServerIndex) {
        RequestResult requestResult = new RequestResult();
        LoginToken loginToken = LoginToken.parseClientToken(clientToken);
        boolean isSceneRight = "Home".equals(sceneName) || "HeartRateBand".equals(sceneName);
        if (loginToken != null && loginToken.isMD5SignRight()
                && loginToken.serverIndex == appServerIndex && isSceneRight) {
            UserLogin userLogin = repository.getUserLogin(loginToken.uid);
            if (userLogin != null
//                && userLogin.getServerIndex() == appServerIndex
                    && userLogin.getToken().equals(loginToken.getLoginTokenForDatabase())
                    && System.currentTimeMillis() < userLogin.getToken_timeout()
            ) {
                requestResult.setData(LoginToken.parseUserLogin(userLogin, appServerIndex).toClientToken());
                return requestResult;
            }
        }
        requestResult.setFailCode();
        return requestResult;
    }

    public RequestResult register(String username, String password, String email, String phone, int appServerIndex) {
        RequestResult requestResult = new RequestResult();
        if (!GlobalConfig.checkServerIndexValid(appServerIndex)) {
            requestResult.setMsg("服务区ID非法");
            requestResult.setFailCode();
        } else if (repository.getUserLogin(username) != null) {
            requestResult.setMsg("该账号已被注册");
            requestResult.setFailCode();
        } else {
            UserLogin userLogin = new UserLogin();
            userLogin.setUsername(username);
            userLogin.setPassword(password);
            userLogin.setServerIndex(appServerIndex);
            boolean res = repository.insertNewUser(userLogin, email, phone);
            if (res) {
                requestResult.setMsg("注册成功");
            } else {
                requestResult.setMsg("注册失败");
                requestResult.setFailCode();
            }
        }
        return requestResult;
    }

    public RequestResult completeUserInfo(
            String username, String password, String nickname, int gender, String birthday,
            String countryCode, String stateCode, String cityCode) {
        RequestResult requestResult = new RequestResult();
        UserLogin userLogin = repository.getUserLogin(username);
        if (userLogin == null) {
            requestResult.setCode(-1);
            requestResult.setMsg("用户不存在");
        } else if (!userLogin.getPassword().equals(password)) {
            requestResult.setCode(-2);
            requestResult.setMsg("验证密码不对");
        } else if (nickname.length() > 64) {
            requestResult.setCode(-3);
            requestResult.setMsg("昵称错误");
        } else if (gender != 1 && gender != 2) {
            requestResult.setCode(-4);
            requestResult.setMsg("性别错误");
        } else if (birthday.length() != 10) {
            requestResult.setCode(-5);
            requestResult.setMsg("生日错误");
        } else if (countryCode == null || stateCode == null || cityCode == null) {
            requestResult.setCode(-6);
            requestResult.setMsg("所在地区错误");
        } else {
            UserInfo userInfo = repository.getUserInfo(userLogin.getId());
            userInfo.setNickname(nickname);
            userInfo.setGender(gender);
            userInfo.setBirthday(birthday);
            userInfo.setCountry(countryCode);
            userInfo.setState(stateCode);
            userInfo.setCity(cityCode);
            repository.updateUserInfo(userInfo);
            requestResult.setMsg("保存成功");
        }
        return requestResult;
    }

    public void setUserOfflineTime(int userID) {
        repository.setUserOfflineTime(userID);
    }

    /**
     *
     * @param identityToken
     * @param appServerIndex
     * @return
     * @throws UnsupportedEncodingException
     */
    public RequestResult loginByApple(
            String identityToken,
            String email,
            String fullName,
            int appServerIndex) throws UnsupportedEncodingException {

        RequestResult requestResult = new RequestResult();
        if (!GlobalConfig.checkServerIndexValid(appServerIndex)) {
            requestResult.setMsg("服务区ID非法");
            requestResult.setFailCode();
            return requestResult;
        }
        JSONObject json = null;
        try {
            //验证identityToken
            if (!AppleUtil.verify(identityToken)) {
                System.out.println("identityToken：授权验证失败");
                requestResult.setMsg("授权验证失败");
                requestResult.setFailCode();
                return requestResult;
            }
            //对identityToken解码
            json = AppleUtil.parserIdentityToken(identityToken);
            if (json == null) {
                System.out.println("identityToken：授权解码失败");
                requestResult.setMsg("授权解码失败");
                requestResult.setFailCode();
                return requestResult;
            }
            System.out.println("验证通过的json信息：" + json);
        } catch (UserException e) {
            requestResult.setMsg(e.toString());
            requestResult.setFailCode();
            return requestResult;
        } catch (Exception e) {
            requestResult.setMsg("apple login 系统错误");
            requestResult.setFailCode();
            return requestResult;
        }

        String appleName = fullName;
        //appleName = new String(appleName.getBytes("ISO-8859-1"), "UTF-8");
        if (appleName == null || appleName.length()<=0){
            if(email == null || email.length()<=0){
                appleName = "user";
            }else{
                appleName = email;
            }
        };
        if (appleName.length() > 64) appleName = appleName.substring(0, 64);

        //ios 没有性别和头像
        //头像
        final String avatarUrl = "";
        //性别
        int sex = 1;

        String sub = json.getString("sub");
        String username = "ios-" + sub;
        String password = "pw-" + sub;
        boolean needBindPhone;
        UserLogin userLogin = repository.getUserLogin(username);
        if (userLogin == null) {
            needBindPhone = true;
            userLogin = new UserLogin();
            userLogin.setUsername(username);
            userLogin.setPassword(password);
            userLogin.setServerIndex(appServerIndex);
            //用户信息
            UserInfo userInfo = new UserInfo();
            userInfo.setNickname(appleName);
            userInfo.setAvatarID( avatarUrl.length() == 0 ?0:-1);//-1
            userInfo.setAvatarUrl(avatarUrl);
            userInfo.setGender(sex);
            //插入用户信息
            boolean res = repository.insertNewUser(userLogin, userInfo);
            if (!res) {
                requestResult.setFailCode();
                requestResult.setMsg("注册失败");
                return requestResult;
            }
        } else {
            int userId = userLogin.getId();
            needBindPhone = GlobalRoot.db.selectOne(UserInfo.class, new SQL() {{
                WHERE("id = " + PARAM(userId));
            }}).getPhone().equals("");
            final boolean needBindPhoneFinal = needBindPhone;
            final String nickname = appleName;
            GlobalRoot.db.update(new SQL() {{
                UPDATE(UserInfo.class);
                SET("avatarUrl = " + PARAM(avatarUrl));
                if (needBindPhoneFinal) {
                    SET("avatarID = " + PARAM(avatarUrl.length() == 0 ?0:-1));
                    SET("nickname = " + PARAM(nickname));
                }
                WHERE("id = " + PARAM(userId));
            }});
        }
        long timeout = getTokenTimeout();
        userLogin.setToken_timeout(timeout);
        LoginToken loginToken = LoginToken.parseUserLogin(userLogin, appServerIndex);
        userLogin.setToken(loginToken.getLoginTokenForDatabase());
        repository.updateUserLogin(userLogin);
        JSONObject data = new JSONObject();
        data.put("token", loginToken.toClientToken());
        data.put("needBindPhone", needBindPhone);
        requestResult.setData(data);
        requestResult.setMsg("登录成功");
        return requestResult;
    }


    public RequestResult deleteUserByApple(
            String identityToken,
            int appServerIndex) throws UnsupportedEncodingException {

        RequestResult requestResult = new RequestResult();
        if (!GlobalConfig.checkServerIndexValid(appServerIndex)) {
            requestResult.setMsg("服务区ID非法");
            requestResult.setFailCode();
            return requestResult;
        }
        if(!AppleUtil.appleRevoke(identityToken))
        {
            requestResult.setMsg("apple:注销用户失败");
            requestResult.setFailCode();
            return requestResult;
        }
        JSONObject data = new JSONObject();
        data.put("token", identityToken);
        requestResult.setData(data);
        requestResult.setMsg("删除成功");
        return requestResult;
    }

    //返回一个token过期时间
    private long getTokenTimeout(){
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime thirtyDaysLater = now.plusDays(loginTime_day);
        long millis = thirtyDaysLater.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
        return millis;
    }
}
