from collections.abc import Collection

import pandas as pd

from config.models import Participant, Screen
from setup import db_engine, session

screen_status = {0: "off", 1: "on", 2: "locked", 3: "unlocked"}


def get_screen_data(usernames: Collection) -> pd.DataFrame:
    """
    Read the data from the screen table and return it in a dataframe.

    Parameters
    ----------
    usernames: Collection
        A list of usernames to put into the WHERE condition.

    Returns
    -------
    df_screen: pd.DataFrame
        A dataframe of screen data.
    """
    query_screen = (
        session.query(Screen, Participant.username)
        .filter(Participant.id == Screen.participant_id)
        .filter(Participant.username.in_(usernames))
    )
    with db_engine.connect() as connection:
        df_screen = pd.read_sql(query_screen.statement, connection)
    return df_screen


def identify_screen_sequence(df_screen: pd.DataFrame) -> pd.DataFrame:
    # TODO Implement a method that identifies "interesting" sequences of screen statuses.
    # The main one are:
    # - OFF -> ON -> unlocked (a true phone unlock)
    # - OFF -> ON -> OFF/locked (no unlocking, i.e. a screen status check)
    # Consider that screen data is sometimes unreliable as shown in expl_screen.ipynb:
    # "I have also seen
    # off -> on -> unlocked (with 2 - locked missing)
    # and
    # off -> locked -> on -> off -> locked (*again*)."
    # Either clean the data beforehand or deal with these inconsistencies in this function.
    pass


def time_screen_sequence(df_screen: pd.DataFrame) -> pd.DataFrame:
    # TODO Use the results of indentify_screen_sequence to calculate time statistics related to transitions.
    # For example, from the two main sequences outlined above, the time of "real" phone usage can be calculated,
    #   i.e. how long the screen was unlocked.
    # Another example might be the average time between screen unlocks and/or screen status checks.
    pass
