import click
from pathlib import Path
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import time
import logging
from typing import Optional

from .compiler import PromptCompiler


class PromptWatcher(FileSystemEventHandler):
    def __init__(self, compiler: PromptCompiler):
        self.compiler = compiler

    def on_modified(self, event):
        if not event.is_directory and event.src_path.endswith(
            f".{self.compiler.file_extension}"
        ):
            self.compiler.compile_file(Path(event.src_path))


@click.group()
@click.option(
    "--extension",
    "-e",
    default="mdx",
    help="Template file extension to look for",
)
@click.option(
    "--output",
    "-o",
    type=click.Path(path_type=Path),
    help="Output directory for generated files",
)
@click.pass_context
def cli(ctx, extension: str, output: Optional[Path]):
    """Prompt compiler CLI"""
    logging.basicConfig(level=logging.INFO)
    ctx.ensure_object(dict)
    ctx.obj["extension"] = extension
    ctx.obj["output"] = output


@cli.command()
@click.argument(
    "directory", type=click.Path(exists=True, path_type=Path), default=Path(".")
)
@click.pass_context
def build(ctx, directory: Path):
    """Compile all template files in directory"""
    compiler = PromptCompiler(
        working_dir=directory,
        file_extension=ctx.obj["extension"],
        output_dir=ctx.obj["output"],
    )
    compiler.compile_all()


@cli.command()
@click.argument(
    "directory", type=click.Path(exists=True, path_type=Path), default=Path(".")
)
@click.pass_context
def watch(ctx, directory: Path):
    """Watch directory for template file changes and recompile"""
    compiler = PromptCompiler(
        working_dir=directory,
        file_extension=ctx.obj["extension"],
        output_dir=ctx.obj["output"],
    )

    # Initial build
    compiler.compile_all()

    # Setup watchdog
    observer = Observer()
    observer.schedule(PromptWatcher(compiler), str(directory), recursive=True)
    observer.start()

    try:
        click.echo(
            f"Watching for .{compiler.file_extension} files in {directory}...\n"
            "Press Ctrl+C to stop."
        )
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        click.echo("\nStopping watch mode...")
        observer.stop()
    observer.join()


if __name__ == "__main__":
    cli()  # pylint: disable=no-value-for-parameter
