import subprocess
import sys
from importlib import resources
from pathlib import Path

from jinja2 import Template
from watchfiles import watch

from ssb_pubmd import templates
from ssb_pubmd.adapters.content_parser import MimirContentParser
from ssb_pubmd.adapters.document_processor import PandocDocumentProcessor
from ssb_pubmd.adapters.publish_client import PublishClient
from ssb_pubmd.adapters.publish_client import get_publish_client
from ssb_pubmd.adapters.storage import LocalFileStorage
from ssb_pubmd.config import Config
from ssb_pubmd.domain.document_publisher import sync_document


def run_cli(system_arguments: list[str], config: Config) -> None:
    match system_arguments:
        case [_, "create", filename]:
            _create_template(filename, config)
        case [_, "preview", filename]:
            _preview(filename, config)
        case _:
            print("Usage:")
            print("  ssb-pubmd create FILENAME")
            print("  ssb-pubmd preview FILENAME")
            sys.exit(1)


def _create_template(filename: str, config: Config) -> None:
    destination = Path.cwd() / filename
    if destination.suffix != ".qmd":
        print("The destination file path must have the '.qmd' extension.")
        sys.exit(1)

    with resources.open_text(templates, "template.qmd") as file:
        raw_template = file.read()

    rendered_template = Template(raw_template).render(
        filepath=destination,
        cms_admin_url=config.publish_base_url + config.publish_admin_path,
        project_folder=destination.parent.name,
        filename=destination.name,
    )
    destination.write_text(rendered_template)
    print(
        f"Successfully created template file {destination}.\n",
        "Open the file for further instructions.",
    )


def _preview(file_path: str, config: Config) -> None:
    if Path(file_path).suffix != ".qmd":
        print("Only Quarto Markdown (.qmd) files are supported.")
        sys.exit(1)

    publish_client = get_publish_client(config)

    _sync_updated_file(file_path, publish_client)

    print("Watching for file changes...")
    for changes in watch(file_path):
        print("Found changes:")
        print(changes)
        _sync_updated_file(file_path, publish_client)

def _sync_updated_file(file_path: str, publish_client: PublishClient) -> None:
    print("Syncing updated document...")
    preview_url = _sync_quarto_file(file_path, publish_client)
    print(f"Content synced successfully. Preview URL: {preview_url}")

def _sync_quarto_file(file_path: str, publish_client: PublishClient) -> str:
    pandoc_document = _quarto_to_pandoc(file_path)
    adapters = (
        PandocDocumentProcessor(),
        MimirContentParser(),
        LocalFileStorage(project_folder=Path(file_path).parent),
        publish_client,
    )
    return sync_document(pandoc_document, *adapters)


def _quarto_to_pandoc(file_path: str) -> str:
    try:
        result = subprocess.run(
            [
                "quarto",
                "render",
                file_path,
                "--to",
                "json",
                "-M",
                "include:false",
                "--output",
                "-",
            ],
            text=True,
            capture_output=True,
            check=True,
        )
        return result.stdout
    except subprocess.CalledProcessError as err:
        message = err.stderr.strip() or "Quarto failed with no error output"
        raise RuntimeError(f"Quarto render failed:\n{message}") from err
