import streamlit as st
import pandas as pd
import altair as alt

from backend.db import Session


def stats_ui(session: Session, grades_table: pd.DataFrame, grades: list):
    with st.expander('Statistiken'):
        number_students = len(session.points_df)
        number_participants = len(session.points_df[session.points_df['Punkte'].notna()])

        if number_participants > 0:
            # Convert from categorical strings to numerical values
            points_table = session.points_df.reset_index()[['Punkte', 'Note']].copy().dropna()
            points_table['Note'] = points_table['Note'].apply(lambda x: float(f'{x}'.replace(',', '.')))
            grades_tab = grades_table['Note'].apply(lambda x: float(f'{x}'.replace(',', '.')))

            score_hist = pd.DataFrame({'Anzahl': [0] * len(grades_tab)}, index=grades_tab)
            counts = pd.DataFrame(points_table['Note'].value_counts().rename('Anzahl'))
            score_hist.update(counts)
            score_hist.reset_index(inplace=True)

            hist = alt.Chart(score_hist).mark_bar().encode(
                x=alt.X('Anzahl:Q', axis=alt.Axis(title='Anzahl', tickCount=score_hist['Anzahl'].max()+1, grid=True)),
                y=alt.Y('Note:O', bin=alt.Bin(binned=True), axis=alt.Axis(title='Note', grid=True))
            )

            median = alt.Chart(points_table).mark_rule(color='blue', opacity=0.5).encode(
                y = 'median(Note):O',
                size=alt.value(5),
            )

            mean = alt.Chart(points_table).mark_rule(color='orange', opacity=0.5, strokeDash=[5,5]).encode(
                y = 'mean(Note):O',
                size=alt.value(5),
            )

            chart = (hist + median + mean)

            st.altair_chart(chart, use_container_width=True)

            passed = 1-score_hist.iloc[-1]["Anzahl"]/number_participants
            1-score_hist.iloc[-1]["Anzahl"]/number_participants
            left, mid, right, rightmost = st.columns(4)
            with left:
                st.write(f'Anzahl Anmeldungen: {number_students}')
                st.write(f'Anzahl Teilnehmer: {number_participants}')
            with mid:
                st.write(f'Bestanden: :green[{passed*100:.2f} %]')
                st.write(f'Durchgefallen: :red[{100-passed*100:.2f}%]')
            with right:
                st.write(f'Punkteuntergrenzen: :gray[(1,0)] {session.grade_1_0:.2f}% / :gray[(4,0)] {session.grade_4_0:.2f}%')
                st.write(f'Maximalpunktzahl: {session.max_points}')
            with rightmost:
                st.write(f':orange[Durchschnitt:] {points_table["Note"].mean():.2f}')
                st.write(f':blue[Median:] {points_table["Note"].median():.2f}')
        else:
            st.write(':orange[Keine Teilnehmer]')