import argparse
import importlib
import logging
import logging.handlers
import sys
from datetime import datetime
from pathlib import Path

from .base import BaseSolver
from .utils.api import FileHandlerAPI, LoggerAPIHandler, ProgressAPI, dump_answer
from .utils.files import SimpleFileHandler
from .utils.progress import ProgressNone, ProgressTQDM


def main():
    parser = argparse.ArgumentParser("Holt59 Advent-Of-Code Runner")
    parser.add_argument("-v", "--verbose", action="store_true", help="verbose mode")
    parser.add_argument("-t", "--test", action="store_true", help="test mode")
    parser.add_argument("-a", "--api", action="store_true", help="API mode")
    parser.add_argument(
        "-o",
        "--output",
        type=Path,
        default=Path("files"),
        help="output folder for created files",
    )
    parser.add_argument(
        "-u", "--user", type=str, default="holt59", help="user input to use"
    )
    parser.add_argument(
        "--stdin",
        action="store_true",
        default=False,
        help="use stdin as input",
    )
    parser.add_argument(
        "-i",
        "--input",
        type=Path,
        default=None,
        help="input to use (override user and test)",
    )
    parser.add_argument("-y", "--year", type=int, help="year to run", default=2024)
    parser.add_argument("day", type=int, help="day to run")

    args = parser.parse_args()

    verbose: bool = args.verbose
    api: bool = args.api
    test: bool = args.test
    stdin: bool = args.stdin
    user: str = args.user
    files_output: Path = args.output
    input_path: Path | None = args.input

    year: int = args.year
    day: int = args.day

    logging.basicConfig(
        level=logging.INFO if verbose else logging.WARNING,
        handlers=[LoggerAPIHandler()] if api else None,
    )

    if input_path is None:
        input_path = Path(__file__).parent.joinpath(
            "inputs", "tests" if test else user, str(year), f"day{day}.txt"
        )
    assert input_path.exists(), f"{input_path} missing"

    solver_class: type[BaseSolver] = importlib.import_module(
        f".{year}.day{day}", __package__
    ).Solver

    solver = solver_class(
        logging.getLogger("AOC"),
        verbose=verbose,
        year=year,
        day=day,
        progress=ProgressAPI()
        if api
        else ProgressTQDM()
        if verbose
        else ProgressNone(),  # type: ignore
        files=FileHandlerAPI(files_output)
        if api and verbose
        else SimpleFileHandler(logging.getLogger("AOC"), files_output)
        if verbose
        else None,
    )

    data: str
    if stdin:
        data = sys.stdin.read()
    else:
        with open(input_path) as fp:
            data = fp.read()

    start = datetime.now()
    last = start

    it = solver.solve(data.rstrip())

    if it is None:
        solver.logger.error(f"no implementation for {year} day {day}")
        exit()

    for i_answer, answer in enumerate(it):
        current = datetime.now()

        if api:
            dump_answer(
                part=i_answer + 1,
                answer=answer,
                answer_time=current - last,
                total_time=current - start,
            )
        else:
            print(
                f"answer {i_answer + 1} is {answer} (found in {(current - last).total_seconds():.2f}s)"
            )

        last = current