import time
import json
import pytz
from datetime import datetime
from flask import Flask,request,redirect,jsonify
from flask_cors import CORS

from sdgb import qr_api
from logout import logout
from login import login
from ticket import get_ticket
from charge import charge
from userdata import userdata
from mapstock import music_with_retry as mapstock
from music import music_with_retry as music
from unlock_all import music_with_retry as unlock



app = Flask(__name__)
app.json.sort_keys = False
CORS(app)

@app.errorhandler(404)
def page_not_found(e):
    return jsonify({"status": "404 Not Found", "timestamp": int(time.time()), "info": "The route you are trying to access is missing.", "date": datetime.now(pytz.timezone('Asia/Shanghai')).strftime('%a, %d %b %Y %H:%M:%S GMT+8')}), 404

@app.errorhandler(405)
def method_not_allowed(e):
    return jsonify({"status": "405 Method Not Allowed", "timestamp": int(time.time()), "info": "You are using the wrong method. Check the docs.", "date": datetime.now(pytz.timezone('Asia/Shanghai')).strftime('%a, %d %b %Y %H:%M:%S GMT+8')}), 405

@app.errorhandler(400)
def method_not_allowed(e):
    return jsonify({"status": "400 Bad Request", "timestamp": int(time.time()), "info": "Something went Wrong.", "date": datetime.now(pytz.timezone('Asia/Shanghai')).strftime('%a, %d %b %Y %H:%M:%S GMT+8')}), 400


@app.route("/")
def index():
    return jsonify({"status": "200 OK", "timestamp": int(time.time()), "info": "Project Fragrance","availableApi": ["qr", "ticket", "mapstock", "unlock"], "date": datetime.now(pytz.timezone('Asia/Shanghai')).strftime('%a, %d %b %Y %H:%M:%S GMT+8')}), 200

@app.route("/qr")
def qr_to_userid():
    qrCode = request.args.get('qrcode')
    if qrCode is None:
        return jsonify({"apiName": "qrCode_to_userId", "apiInfo": "Transfer qrCode from WeChat to userId", "apiUsage": "/qr?qrcode=<qrcode>"})
    else:
        qr_result = qr_api(qrCode)
        if qr_result['userID'] == -1 or len(str(qr_result['userID'])) != 8:
            returnCode = 404
            status = "404 Not Found"
            info = "Your QrCode is invald."
            userId = ""
        elif len(str(qr_result['userID'])) == 8:
            returnCode = 200
            status = "200 OK"
            info = "Succeed."
            userId = qr_result['userID']
        else:
            returnCode = 500
            status = "500 Internal Server Error"
            info = "Unknown Error. Failed in transfering qrCode to userId."
            userID = ""
        data = jsonify({"status": status, "timestamp": int(time.time()), "info": info, "apiName": "qrCode_to_userId", "date": datetime.now(pytz.timezone('Asia/Shanghai')).strftime('%a, %d %b %Y %H:%M:%S GMT+8'), "userId": userId})
        return data, returnCode

@app.route("/ticket")
def ticket():
    userId = request.args.get('userid')
    if userId is None or userId.isdigit() is False or len(str(userId)) != 8:
        return jsonify({"apiName": "ticket", "apiInfo": "Send x6 Ticket", "apiUsage": "/ticket?userid=<userId>"})
    else:
        userId = int(userId)
        timestamp = int(time.time())
        charge_data = charge(userId)
        if charge_data['userChargeList'][2]['stock'] == 0:
            login_data = login(userId, timestamp)
            if login_data['returnCode'] == 102:
                returnCode = 403
                status = "403 Forbidden"
                info = "Unable to operate. Please refresh QrCode."
                log = []
            elif login_data['returnCode'] == 100:
                returnCode = 403
                status = "403 Forbidden"
                info = "Unable to operate. Probably User has logged in."
                log = []
            elif login_data['returnCode'] == 1:
                ticket_data = get_ticket(userId)
                if ticket_data['returnCode'] == 0:
                    logout(userId, timestamp)
                    returnCode = 405
                    status = "405 Method Not Allowed"
                    info = "WARNING: THIS INFO SHOULD NEVER APPEARS. IF YOU SEE THIS WARNING PLEASE CONTACT Telegram@sasakure. Unable to operate. Successfully Logged in. Probably User has had one ticket."
                    log = {"UserLoginApiStatus": 1, "UserLogoutApiStatus": 1}
                elif ticket_data['returnCode'] == 1:
                    logout(userId, timestamp)
                    returnCode = 200
                    status = "200 OK"
                    info = "Succeed."
                    log = {"UserLoginApiStatus": 1, "UpsertUserChargelogStatus": 1, "UserLogoutApiStatus": 1}
            else:
                returnCode = 500
                status = "500 Internal Server Error"
                info = "Unknown Error. Failed in UserLogin"
                log = login_data
        elif charge_data['userChargeList'][2]['stock'] == 1:
            returnCode = 403
            status = "403 Forbidden"
            info = "User has had a ticket."
            log = []
        else:
            returnCode = 500
            status = "500 Internal Server Error"
            info = "Unknown Error. Failed in GetUserCharge"
            log = charge_data
        data = jsonify({"status": status, "timestamp": timestamp, "info": info, "apiName": "ticket", "date": datetime.now(pytz.timezone('Asia/Shanghai')).strftime('%a, %d %b %Y %H:%M:%S GMT+8'), "userId": userId})
        return data, returnCode

@app.route("/mapstock")
def mapstock():
    userId = request.args.get('userid')
    if userId is None or userId.isdigit() is False or len(str(userId)) != 8:
        return jsonify({"apiName": "mapstock", "apiInfo": "Save 99 Kilometers in Maps.", "apiUsage": "/mapstock?userid=<userId>"})
    else:
        userId = int(userId)
        timestamp = int(time.time())
        login_data = login(userId, timestamp)
        if login_data['returnCode'] == 102:
            returnCode = 403
            status = "403 Forbidden"
            info = "Unable to operate. Please refresh QrCode."
            log = []
        elif login_data['returnCode'] == 100:
            returnCode = 403
            status = "403 Forbidden"
            info = "Unable to operate. Probably User has logged in."
            log = []
        elif login_data['returnCode'] == 1:
            userdata_result = userdata(userId)
            logout(userId, timestamp)
            if userdata_result['userData']['mapStock'] == 99000:
                returnCode = 403
                status = "403 Forbidden"
                info = "User has stocked 99 kilometers."
                log = []
            else:
                while True:
                    login(userId, timestamp)
                    userdata_result = userdata(userId)
                    logout(userId, timestamp)
                    if userdata_result['userData']['mapStock'] == 99000:
                        returnCode = 200
                        status = "200 OK"
                        info = "Succeed."
                        log = {"UserLoginApiStatus": 1, "UploadUserPlaylogApiStatus": 1, "UpsertUserAllApi": 1, "UserLogoutApiStatus": 1}
                        break
                    else:
                        mapstock(userId)
                        continue
        else:
            returnCode = 500
            status = "500 Internal Server Error"
            info = "Unknown Error. Failed in UserLogin"
            log = login_data
        data = jsonify({"status": status, "timestamp": timestamp, "info": info, "apiName": "mapstock", "date": datetime.now(pytz.timezone('Asia/Shanghai')).strftime('%a, %d %b %Y %H:%M:%S GMT+8'), "userId": userId})
        return data, returnCode

@app.route("/unlock")
def unlock():
    userId = request.args.get('userid')
    if userId is None or userId.isdigit() is False or len(str(userId)) != 8:
        return jsonify({"apiName": "unlock", "apiInfo": "Unlock All DX Master Charts.", "apiUsage": "/unlock?userid=<userId>"})
    else:
        userId = int(userId)
        unlock(userId)
        returnCode = 200
        status = "200 OK"
        info = "Succeed."
        log = {"UserLoginApiStatus": 1, "UploadUserPlaylogApiStatus": 1, "UpsertUserAllApi": 1, "UserLogoutApiStatus": 1}
        data = jsonify({"status": status, "timestamp": timestamp, "info": info, "apiName": "unlock", "date": datetime.now(pytz.timezone('Asia/Shanghai')).strftime('%a, %d %b %Y %H:%M:%S GMT+8'), "userId": userId})
        return data

@app.route("/music", methods=['POST'])
def music_post():
    request_data = request.get_json()
    if 'userId' in request_data and 'music' in request_data:
        if request_data['userId'] is None or isinstance(request_data['userId'], int) is False or len(str(request_data['userId'])) != 8:
            return jsonify({"apiName": "music", "apiInfo": "Overwrite Music Data in UserData.", "apiUsage": ""})
        else:
            userId = int(request_data['userId'])
            timestamp = int(time.time())
            login_data = login(userId, timestamp)
            if login_data['returnCode'] == 102:
                returnCode = 403
                status = "403 Forbidden"
                info = "Unable to operate. Please refresh QrCode."
                log = []
            elif login_data['returnCode'] == 100:
                returnCode = 403
                status = "403 Forbidden"
                info = "Unable to operate. Probably User has logged in."
                log = []
            elif login_data['returnCode'] == 1:
                logout(userId, timestamp)
                music_data = request_data['music']
                music(userId, music_data)
                returnCode = 200
                status = "200 OK"
                info = "Operation was Su."
                log = {"UserLoginApiStatus": 1, "UploadUserPlaylogApiStatus": 1, "UpsertUserAllApi": 1,"UserLogoutApiStatus": 1}
            else:
                returnCode = 500
                status = "500 Internal Server Error"
                info = "Unknown Error. Failed in UserLogin"
                log = login_data
    else:
        return jsonify({"apiName": "music", "apiInfo": "Overwrite Music Data in UserData.", "apiUsage": ""})
    data = jsonify({"status": status, "timestamp": timestamp, "info": info, "apiName": "music", "date": datetime.now(pytz.timezone('Asia/Shanghai')).strftime('%a, %d %b %Y %H:%M:%S GMT+8'), "userId": userId})
    return data, returnCode

if __name__ == '__main__':
    app.run(port = 8080, debug=True)