import logging
import os
import sys
from pathlib import Path

import typer
from rich.console import Console
from rich.logging import RichHandler

from tilemapper import battlemap
from tilemapper import tileset as _tileset

app = typer.Typer()
app_state = {}


@app.callback(invoke_without_command=True)
def main(
    ctx: typer.Context,
    config_dir: Path = typer.Option(
        default=Path(__file__).parent.parent / "tilesets",
        help="The path containing tile sets to load."
    ),
    verbose: bool = typer.Option(default=False, help="If True, increase verbosity of status messages."),
):
    app_state["tileset_manager"] = _tileset.TileSetManager(config_dir)
    app_state["config_dir"] = config_dir
    app_state["verbose"] = verbose
    debug = os.getenv("DEBUG", None)
    logging.basicConfig(
        format="%(name)s %(message)s",
        level=logging.DEBUG if debug else logging.INFO,
        handlers=[RichHandler(rich_tracebacks=True, tracebacks_suppress=[typer])],
    )


@app.command()
def list():
    """
    List available tile sets.
    """
    manager = app_state["tileset_manager"]
    print("\n".join(manager.available))


@app.command()
def inspect(source: Path = typer.Argument(help="The battle map text file to laod.")):
    """
    Print information about  the specified battle map text file.
    """
    manager = app_state["tileset_manager"]
    bmap = battlemap.BattleMap(name=source.name, source=source, tileset=manager.console_map_colorized)
    bmap.load()
    console = Console()
    console.print(repr(bmap), highlight=False)


@app.command()
def render(
        source: Path = typer.Argument(help="The battle map text file to load."),
        outfile: Path = typer.Argument(help="The file to create."),
        tileset: str = typer.Option(
            help="The name of the tile set to use (run mapper list to see what's available).")):
    """
    Create a PNG image of a battle map using a tile set.
    """
    manager = app_state["tileset_manager"]
    if tileset not in manager.available:
        raise RuntimeError(f"Could not locate the tile set {tileset} in {manager.config_dir}.")

    try:
        bmap = battlemap.BattleMap(name=source.name, source=source, tileset=manager.load(tileset))
    except _tileset.MissingTileException as e:
        logging.error(e)
        sys.exit(1)

    try:
        bmap.load()
    except battlemap.UnsupportedTileException as e:
        logging.error(e)
        sys.exit(1)

    image = bmap.render()
    # image = image.resize((int(0.5 * image.size[0]), int(0.5 * image.size[1])))
    image.save(outfile)
    print(f"Wrote {outfile.stat().st_size} bytes to {outfile}")


if __name__ == "__main__":
    app()
