import argparse
import sys
from pathlib import Path

from rich.console import Console
from rich.text import Text

from ._console import ConsoleGraderReporter
from gradema.section import Section
from gradema.grader import grade_section


RESULTS_PATH = Path("results.txt")


def save_score(points: int) -> None:
    # It is necessary to remove results.txt before writing to it because if a student wrote to results.txt and changed its permissions, we couldn't write to it
    RESULTS_PATH.unlink(missing_ok=True)
    with RESULTS_PATH.open("w") as file:
        print(points, file=file)


def welcome(console: Console) -> None:
    console.print("Welcome to Gradema!")
    console.print("This script will grandma you through completing this programming assignment")
    console.line()
    console.print(f"    [magenta]Magenta[/magenta] is bash/shell commands.")
    console.print(f"    [green]Green[/green] is used to indicate a pass.")
    console.print(f"    [red]Red[/red] is used to indicate a fail.")
    console.print(f"    [orange_red1]Orange[/orange_red1] marks the text of a header for a block of tests of a single type.")
    console.print(f"    [cyan]Cyan[/cyan] draws your attention to something you have to do..")
    console.line()
    console.print(Text.assemble("Actually ", ("read ALL the output generated by this script!", "cyan")))

    console.print(f"[blue]{'=' * console.width}[/blue]")


def run_grader(args: list[str], section: Section) -> int:
    if not section.is_pointed:
        raise ValueError("The root section must be pointed!")
    assert section.points is not None
    parser = argparse.ArgumentParser(
        prog="Gradema Autograder",
        epilog="Gradema - created by Lavender Shannon for Dr. Taylor",
    )
    parser.add_argument("-g", "--grade", action="store_true")
    parser.add_argument("-d", "--debug", action="store_true")
    try:
        parsed_args = parser.parse_args(args)
    except SystemExit as e:
        code = e.code
        assert isinstance(code, int)
        return code

    # Useful documentation here: https://rich.readthedocs.io/en/latest/markup.html
    console = Console(soft_wrap=True)
    welcome(console)

    interactive = True
    debug_mode = True
    if not parsed_args.debug:
        if parsed_args.grade:
            debug_mode = False
            # TODO determine if we are in an interactive terminal and set interactive accordingly
            # set interactive to False for now
            interactive = False
        else:
            try:
                console.print("Press [cyan]Enter[/cyan] now to continue")
                input()
            except EOFError:
                interactive = False
                debug_mode = False

        if interactive and debug_mode:  # if debug mode was set to False, then the --grade option must have been specified
            console.print(
                """Which of the following modes do you want to run in?
        1) debug+grade mode (d)
        2) grade only mode (g)
    Type 'd' or 'g', then hit [cyan]Enter[/cyan]."""
            )
            mode_input = input()
            debug_mode = mode_input == "" or mode_input[0].lower() != "g"

    reporter = ConsoleGraderReporter(
        section,
        console,
        sys.stdout,
        sys.stderr,
        interactive=interactive,
        debug_mode=debug_mode,
        depth=0,
    )
    points = grade_section(reporter, section.points, section)
    save_score(points)
    passing = points >= 70
    console.line()
    console.print("=" * console.width, style="green" if passing else "red")
    console.print(f"Your total grade is:\n{points}")
    console.line()
    if points == 100:
        console.print("It's perfect! Congratulations!", style="green")
        return 0
    elif passing:
        console.print("You're passing; decide how much you want the extra points!", style="green")
        return 0
    else:
        console.print("You're not passing yet.", style="red")
        return 1
