import pandas
from flask import Flask, render_template
from matplotlib import pyplot as plt
from numpy import vectorize
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, accuracy_score
from sklearn.model_selection import train_test_split

app = Flask(__name__)


@app.route("/")
def home():
    return "<html>" \
           "<h1>Жукова Алина ПИбд-41</h1>" \
           "<h1>Лабораторная работа №5</h1>" \
           "<table>" \
           "<td>" \
           "<form Action='http://127.0.0.1:5000/k4_1_task_5' Method=get>" \
           "<input type=submit value='Регрессия'>" \
           "</form>" \
           "</td>" \
           "</table>" \
           "</html>"

# Регрессия
# 10 вариант - Линейная регрессия
@app.route("/k4_1_task_5", methods=['GET'])
def k4_1_task_5():
    data = pandas.read_csv('Data_chess_games.csv')
    data = data.loc[data['created_at'] - data['last_move_at'] != 0]
    data = data.drop_duplicates()
    data = data.sample(n=5000, replace=True, random_state=1)

    # отбор нужных столбцов
    corr = data[['white_rating', 'black_rating', 'moves', 'opening_eco', 'opening_name', 'winner']]
    def SplitPr(stroke):
        return len(stroke.split(" "))
    corr['len'] = corr['moves'].apply(SplitPr)
    corr = corr.loc[corr['len'] >= 10]

    number_element = 0
    def SelectElemToStolb(elem):
        return elem.split(" ")[number_element]

    def ScoreXod(elem):
        if(elem == "O-O" or elem == "O-O-O"):
            return 50
        if(elem.__contains__("x")):
            return 20
        if (elem.__contains__("+")):
            return 50
        return 10

    def EcoToScore(elem):
        score_eco = 0
        if(str(elem).startswith("A")):
            score_eco = 100
        if (str(elem).startswith("B")):
            score_eco = 200
        if (str(elem).startswith("C")):
            score_eco = 300
        if (str(elem).startswith("D")):
            score_eco = 400
        if (str(elem).startswith("E")):
            score_eco = 500
        score_eco += int(str(elem)[1:])
        return score_eco

    # 0 - white  ||  1 - black
    gamer_ind = 0
    def ScoreAllXods(elem):
        score = 0
        xods = elem.split(" ")
        ind_temp = 0
        for xod in xods:
            if(ind_temp % 2 == gamer_ind % 2):
                score += ScoreXod(xod)
            ind_temp += 1

        return score

    corr['score_eco'] = corr['opening_eco'].apply(EcoToScore)


    # Ходы
    corr['w_score_all'] = corr['moves'].apply(ScoreAllXods)
    gamer_ind = 1
    corr['b_score_all'] = corr['moves'].apply(ScoreAllXods)

    def WinnerSelect(elem):
        if(elem == "white"):
            return 1
        if(elem == "black"):
            return -1
        return 0
    corr['winner'] = corr['winner'].apply(WinnerSelect)

    y = corr[['winner']]

    # Нормирование к 1
    max_zn = corr['white_rating'].max()
    min_zn = corr['white_rating'].min()
    def normirovanie(elem):
        return ((elem - min_zn) / (max_zn - min_zn))
    corr['white_rating'] = corr['white_rating'].apply(normirovanie)

    max_zn = corr['black_rating'].max()
    min_zn = corr['black_rating'].min()
    corr['black_rating'] = corr['black_rating'].apply(normirovanie)

    corr_st = corr
    corr = corr[['white_rating', 'black_rating', 'b_score_all', 'w_score_all', 'score_eco']]


    X_train, X_test, y_train, y_test = train_test_split(corr, y, test_size=.05, random_state=42)

    linear = LinearRegression()
    linear.fit(X_train, y_train)
    def FunkPorog(elem):
        if(elem >= 0.5):
            return 1
        if(elem > -0.5):
            return 0
        if(elem <= -0.5):
            return -1
    prediction = linear.predict(X_test)
    n_predict_vect = vectorize(FunkPorog)

    # Средняя ошибка
    accuracy_mean_abs_error = mean_absolute_error(prediction, y_test)

    # Предсказание исхода партии, в целых числах
    predict_acc_score = n_predict_vect(prediction)
    accuracy_acc_score = accuracy_score(predict_acc_score, y_test)


    white_win = corr_st.loc[corr_st['winner'] == 1]
    white_score = (white_win['w_score_all'])
    black_score = (white_win['b_score_all'])
    white_win_x = white_score - black_score + white_win['score_eco']
    white_win_y = white_win['winner'] + (white_win['black_rating'] - white_win['white_rating'])

    black_win = corr_st.loc[corr_st['winner'] == -1]

    white_score = (black_win['w_score_all'])
    black_score = (black_win['b_score_all'])
    black_win_x = white_score - black_score + black_win['score_eco']
    black_win_y = black_win['winner'] + (black_win['black_rating'] - black_win['white_rating'])

    no_win = corr_st.loc[corr_st['winner'] == 0]

    white_score = (no_win['w_score_all'])
    black_score = (no_win['b_score_all'])
    no_win_x = white_score - black_score + no_win['score_eco']
    no_win_y = no_win['winner'] + (no_win['black_rating'] - no_win['white_rating'])

    white_win = white_win[['white_rating', 'black_rating', 'b_score_all', 'w_score_all', 'score_eco']]
    black_win = black_win[['white_rating', 'black_rating', 'b_score_all', 'w_score_all', 'score_eco']]
    no_win = no_win[['white_rating', 'black_rating', 'b_score_all', 'w_score_all', 'score_eco']]

    plt.subplot(1, 2, 1)
    plt.scatter(white_win_x, (corr_st.loc[corr_st['winner'] == 1])['winner'], alpha=0.6, s=25, c='red')
    plt.scatter(black_win_x, (corr_st.loc[corr_st['winner'] == -1])['winner'], alpha=0.6, s=25, c='blue')
    plt.scatter(no_win_x, (corr_st.loc[corr_st['winner'] == 0])['winner'], alpha=0.6, s=25, c='green')
    plt.scatter(white_win_x, white_win_y, alpha=0.2, s=25, c='pink')
    plt.scatter(black_win_x, black_win_y, alpha=0.2, s=25, c='cyan')
    plt.scatter(no_win_x, no_win_y, alpha=0.2, s=25, c='yellow')

    plt.savefig('static\k4_1_5_regression.png')

    return "<html>" \
       "<h1>Регрессия</h1>" \
       "<h2>Вариант 10. Задание 5 - Линейная регрессия</h2>" \
       "<h2> Точность модели:</h2>" \
       "<h2> Отклонение по абсолютной ошибке: " + str(accuracy_mean_abs_error) + "</h2>" \
       "<h2> Отклонение по исходу партии в целых числах: " + str(accuracy_acc_score) + "</h2>" \
       "<div align='center'>" + render_template(
       '4_1_l6_figure1.html') + "</div>" \
       "</html>"

if __name__ == "__main__":
    app.run(debug=True)