from flask import render_template, request
from testapp import app
from collections import Counter

# ユーザーごとの点数を格納する辞書
user_score = {}

# playerの数
MAX_PLAYER = 1

# 何位まで表示するか(nemoto)
max_order = 5

# scoreを保存するデータ
data = [0] * MAX_PLAYER
# 　user名を保存するデータ
user = [0] * MAX_PLAYER

# ゲーム中の選択肢を保存
choices = []

# 各回のゲーム結果を保存
frequent_table = ""

# ユーザーを識別するための番号(実際の初期値は０にする)
user_number = 0

data_count = 0

order_table = ""

most_common_option = 0


@app.route("/form", methods=["GET", "POST"])
def index():
    global frequent_table, user_number, data_count, order_table, most_common_option, max_order

    if request.method == "GET":
        return render_template("testapp/index.html")

    if request.method == "POST":
        # ゲーム開始時にユーザー数を出しておき，それぞれに識別番号を振る
        if request.form.get("username"):
            # ユーザー名を取得し，ユーザー情報を登録
            username = request.form.get("username")
            user[user_number] = username
            print("Received name:", username, "UserNumber:", user_number)

            user_number += 1
            # クライアントサイドに識別番号を返す
            return str(user_number - 1)

        # 他のplayerが揃うのを待機(nemoto追記)
        if request.form.get("checkStart"):
            if user_number < MAX_PLAYER:
                return str(MAX_PLAYER)
            # 全員のデータが集まった場合は，ゲーム開始
            else:
                return "START"

        # ゲーム中に選択肢を取得し，集計する
        if request.form.get("choice"):
            if len(choices) >= MAX_PLAYER:
                choices.clear()
            choices.append(request.form.get("choice"))
            print("Received choice:", choices)

            if len(choices) >= MAX_PLAYER:
                frequent_table = calculate_majority(choices)
                return "WAIT"

        # 他の人が終わるまで待機
        if request.form.get("checkothers"):
            if len(choices) < MAX_PLAYER:
                return "WAIT"
            # 全員のデータが集まった場合は，多数派を計算
            else:
                print(frequent_table)
                return frequent_table

        # ゲーム終了時，識別番号とスコアを受け取る
        if request.form.get("number") and request.form.get("score"):
            # 識別番号を取得
            user_number = int(request.form.get("number"))
            # スコアを取得
            score = int(request.form.get("score"))  # nemoto変更
            data[user_number] = score
            print(
                "Received number:",
                user_number,
                "\nUserName:",
                user[user_number],
                "\nScore:",
                data[user_number],
            )
            data_count += 1

            # すべてのデータが集まった場合，順位表を作成 otaki
            if data_count >= MAX_PLAYER:
                scores_order, user_number_order = calculate_order(data)
                print(scores_order, user_number_order)
                order_table = create_order_table(scores_order, user_number_order, max_order)

            return "WAIT"

        # 最終結果を集計
        if request.form.get("checkResult"):
            # 　順位表が作成した場合はそれを返す
            if order_table == "":
                return "WAIT"
            else:
                return order_table

        return "WAIT"


# 多数派の計算
def calculate_majority(get_data):
    counter = Counter(get_data)
    get_frequent_table = ""
    # 最も多く出現する要素を取得する
    most_common = counter.most_common()  # 出現回数が多い順に要素とその出現回数のリストを取得

    # 最も多く出現する要素
    get_most_common_option = str(most_common[0][0])
    get_most_common_count = str(most_common[0][1])
    get_frequent_table += get_most_common_option + " " + get_most_common_count + "\n"
    # 2番目に多い要素
    get_second_most_common_option = str(most_common[1][0]) if len(most_common) > 1 else str(4)
    get_second_most_common_count = str(most_common[1][1]) if len(most_common) > 1 else str(0)
    get_frequent_table += get_second_most_common_option + " " + get_second_most_common_count + "\n"
    # 3番目に多い要素
    get_third_most_common_option = str(most_common[2][0]) if len(most_common) > 2 else str(4)
    get_third_most_common_count = str(most_common[2][1]) if len(most_common) > 2 else str(0)
    get_frequent_table += get_third_most_common_option + " " + get_third_most_common_count + "\n"
    # 4番目に多い要素
    get_fourth_most_common_option = str(most_common[3][0]) if len(most_common) > 3 else str(4)
    get_fourth_most_common_count = str(most_common[3][1]) if len(most_common) > 3 else str(0)
    get_frequent_table += get_fourth_most_common_option + " " + get_fourth_most_common_count
    return get_frequent_table


# ランキング上位の計算
def calculate_order(get_data):
    get_sorted_numbers_with_indices = sorted(enumerate(get_data), key=lambda x: x[1], reverse=True)
    get_scores = [item[1] for item in get_sorted_numbers_with_indices]
    get_labels = [item[0] for item in get_sorted_numbers_with_indices]

    return get_scores, get_labels


# 順位表の作成 otaki(同率の場合も考慮 nemoto)
def create_order_table(scores, labels, max):
    order_table = ""
    j = 0  # 同率順位の考慮

    # 最高"max位"までを表示する
    if max >= MAX_PLAYER:
        max = MAX_PLAYER

    for i in range(max):
        if i + j >= max:  # 参照する配列がこれ以上ない時
            break
        order_table += str(i + 1 + j) + "位" + " " + user[int(labels[i + j])] + " " + str(scores[i + j]) + "pt" + "\n"
        now_order = i + 1 + j  # 今の順位
        if i + j + 1 == max:  # 先ほどorder_tableに挿入した配列が，最後であった時
            break
        # 同じスコアのplayersの処理
        while str(scores[i + j]) == str(scores[i + 1 + j]):
            j += 1
            order_table += (
                str(now_order) + "位" + " " + user[int(labels[i + j])] + " " + str(scores[i + j]) + "pt" + "\n"
            )
            if i + j + 1 >= max:  # (i+j)と比較する配列(i+j+1)がない時
                break

    if order_table.endswith("\n"):
        order_table = order_table[:-1]  # 最後の改行文字を削除
    print("FINAL" + order_table)
    return order_table
