package com.example.demo.module.login;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.common.GlobalRoot;
import com.example.demo.common.MD5Tool;
import com.example.demo.common.RequestResult;
import com.example.demo.module.user.UserComp;
import com.example.demo.table.user.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import pers.jc.sql.SQL;

import java.io.UnsupportedEncodingException;
import java.util.List;

/**
 * 控制器-游戏登陆
 */
@CrossOrigin
@RestController
@RequestMapping("/gameLogin")
public class GameLoginController {
    @Autowired
    GameLoginService service;

    /**
     * 普通登录
     */
    @PostMapping("/loginNormal")
    public RequestResult loginNormal(String username, String password, int serverIndex) {
        return service.login(username, password, serverIndex);
    }

    /**
     * 微信登录
     */
    @PostMapping("/loginByWX")
    public RequestResult loginByWX(String loginCode, int serverIndex) throws UnsupportedEncodingException {
        return service.loginByWX(loginCode, serverIndex);
    }

    /**
     * 苹果登录
     */
    @PostMapping("/loginByApple")
    public RequestResult loginByApple(String identityToken,
                                      String email,
                                      String fullName,
                                      int serverIndex) throws UnsupportedEncodingException {
        return service.loginByApple(identityToken,
                email,
                fullName,
                serverIndex);
    }

    @PostMapping("/deleteUserByApple")
    public RequestResult deleteUserByApple(String identityToken,
                                           int serverIndex) throws UnsupportedEncodingException {

        return service.deleteUserByApple(identityToken,serverIndex);
    }

    /**
     * 用户注册
     */
    @PostMapping("/register")
    public RequestResult register(String username, String password, int serverIndex) {
        return service.register(username, password, "", "", serverIndex);
    }

    @PostMapping("/register2")
    public RequestResult register2(String username, String password,
           String email, String phone, int serverIndex) {
        return service.register(username, password, email, phone, serverIndex);
    }

    /**
     * 用户注册后，完善用户信息的提交处理
     */
    @PostMapping("/completeUserInfo")
    public RequestResult completeUserInfo(
            String username, String password, String nickname, int gender, String birthday,
            String countryCode, String stateCode, String cityCode) {
        return service.completeUserInfo(username, password, nickname, gender, birthday, countryCode, stateCode, cityCode);
    }

    @PostMapping("/loginByToken")
    public RequestResult loginByToken(String token, String sceneName, int serverIndex) {
        return service.loginByToken(token, sceneName, serverIndex);
    }

    @PostMapping("/getUserInfo")
    public RequestResult getUserInfo(String token) {
        RequestResult requestResult = new RequestResult();
        LoginToken loginToken = LoginToken.parseClientToken(token);
        if (!loginToken.isMD5SignRight()) {
            requestResult.setFailCode();
            return requestResult;
        }
        UserInfo userInfo = UserComp.getUserInfo(loginToken.uid);
        if (userInfo == null) {
            requestResult.setFailCode();
            return requestResult;
        }
        requestResult.setData(JSON.toJSONString(userInfo));
        return requestResult;
    }

    @PostMapping("/listUsernamesByEmail")
    public RequestResult listUsernamesByEmail(String email, long timestamp, String sign) {
        return listUsernamesByRelateAccount(0, email, timestamp, sign);
    }

    @PostMapping("/listUsernamesByPhone")
    public RequestResult listUsernamesByPhone(String phone, long timestamp, String sign) {
        return listUsernamesByRelateAccount(1, phone, timestamp, sign);
    }

    private RequestResult listUsernamesByRelateAccount(int relateAccountType, String relateAccount, long timestamp, String sign) {
        RequestResult requestResult = new RequestResult();
        boolean pass = MD5Tool.makeMD5(relateAccount + "~happy~" + timestamp).equals(sign);
        if (pass) pass = System.currentTimeMillis() - timestamp < 30 * 1000;
        if (!pass) {
            requestResult.setCode(-1);
            requestResult.setMsg("签名失效");
            return requestResult;
        }
        List<JSONObject> userList = GlobalRoot.db.select(new SQL(){{
            SELECT("username");
            FROM("user_info");
            JOIN("user_login ON user_info.id = user_login.id");
            if (relateAccountType == 0) WHERE("email=" + PARAM(relateAccount));
            else if (relateAccountType == 1) WHERE("phone=" + PARAM(relateAccount));
            WHERE("username NOT LIKE '%-%'");
        }});
        if (userList.size() <= 0) {
            requestResult.setCode(-2);
            if (relateAccountType == 0) requestResult.setMsg("该邮箱未绑定任何游戏账号");
            else if (relateAccountType == 1) requestResult.setMsg("该手机未绑定任何游戏账号");
            return requestResult;
        }
        for (JSONObject jo : userList) {
            String username = jo.getString("username");
            long ts = System.currentTimeMillis();
            jo.put("timestamp", ts);
            jo.put("sign", MD5Tool.makeMD5(username + "~happy~" + ts));
        }
        requestResult.setData(userList);
        return requestResult;
    }

    @PostMapping("/resetPassword")
    public RequestResult resetPassword(String sign, long timestamp, String username, String password) {
        RequestResult requestResult = new RequestResult();
        boolean pass = MD5Tool.makeMD5(username + "~happy~" + timestamp).equals(sign);
        if (pass) pass = System.currentTimeMillis() - timestamp < 60 * 60 * 1000;
        if (!pass) {
            requestResult.setCode(-1);
            requestResult.setMsg("签名失效");
            return requestResult;
        }
        int count = GlobalRoot.db.update(new SQL(){{
            UPDATE("user_login");
            SET("password = " + PARAM(password));
            WHERE("username = " + PARAM(username));
        }});
        if (count < 1) {
            requestResult.setCode(-2);
            requestResult.setMsg("重置密码失败");
            return requestResult;
        }
        requestResult.setMsg("重置密码成功");
        return requestResult;
    }
}
