import shutil
from pathlib import Path

import typer
import yaml
from pydantic_settings import BaseSettings

from telegraph.config import Settings


def make_yaml_config_file(settings: BaseSettings, location: Path) -> None:
    # make default config file for application in application directory
    """
    Create YAML config files for given settings class.

    Will create a default configuration file for the application in the
    application directory if it does not exist. The file will contain a
    header warning not to edit it and a dump of the settings class.

    The file is written in YAML format.

    Parameters
    ----------
    settings : type[BaseSettings]
        The settings class to create the config file for.

    Returns
    -------
    None
    """
    if not location.exists():
        location.parent.mkdir(parents=True, exist_ok=True)
        with open(location, "a") as f:
            text = """#
# This file was automatically generated by telegraph.
# Copy this file to $HOME/.telegraph/ and remove "default-" from 
# the name to override with user settings. 
# DO NOT edit this file; IT WILL BE OVERWRITTEN.\n#\n#\n
# DO NOT COMMIT CONFIDENTIAL DATA TO VERSION CONTROL. \n#\n#\n#
"""
            f.write(text)
            yaml.dump(settings.model_dump(), f)
            typer.echo(f"Created config file {str(location)}.")
    else:
        typer.echo(f"File {str(location)} already exists. Overwriting.")
        with open(location, "w") as f:
            text = """#
# This file was automatically generated by telegraph.
# Copy this file to $HOME/.telegraph/ and remove "default-" from 
# the name to override with user settings. 
# DO NOT edit this file; IT WILL BE OVERWRITTEN.\n#\n#\n
# DO NOT COMMIT CONFIDENTIAL DATA TO VERSION CONTROL. \n#\n#\n#
"""
            f.write(text)
            yaml.dump(settings.model_dump(), f)
    typer.echo("Done.")


def initial_setup() -> None:
    config = Settings()

    # create default directories
    typer.echo("Creating default directories.")
    Path(config.projects_dir).mkdir(exist_ok=True, parents=True)
    Path(config.config_dir).mkdir(exist_ok=True, parents=True)
    typer.echo("Done.")

    typer.echo("Adding symlink for project directory to app directory.")
    try:
        (Path(config.app_dir) / "projects").symlink_to(Path(config.projects_dir))
    except FileExistsError:
        typer.echo(f"Existing projects directory found at {config.projects_dir}")
    typer.echo("Done.")

    # create default config file in app dir
    typer.echo("Creating default app config.")
    make_yaml_config_file(
        settings=config, location=Path(config.app_dir) / "telegraph-default-config.yaml"
    )
    typer.echo("Done.")

    typer.echo("Initial setup complete.")


def new_project_setup(project_name: str) -> None:
    config = Settings()

    typer.echo("Setting up new project.")
    typer.echo("Creating new project directories.")
    project_dir = Path(config.projects_dir) / project_name
    project_dir.mkdir()

    dirs = [
        "data",
        "templates",
        "rendered_templates",
    ]

    for d in dirs:
        (project_dir / d).mkdir()

    typer.echo("Done.")

    typer.echo("Creating template base files.")
    template_dir = project_dir / "templates"
    (template_dir / "body.html.j2").touch()
    (template_dir / "body.txt.j2").touch()
    (template_dir / "subject.txt.j2").touch()
    typer.echo("Done.")

    typer.echo("Creating python pipeline template.")
    app_dir = Path(config.app_dir).resolve()
    shutil.copy(
        (app_dir / "telegraph" / "util" / "pipeline_base.py"),
        (project_dir / "pipeline.py"),
    )
    typer.echo("Done")

    typer.echo(f"{project_name} project setup complete.")
