import typer
from pathlib import Path
from cookiecutter.main import cookiecutter
from config import TEMPLATES, STORAGE_PATHS


# INPUT
def collect_inputs():
    """
    Collects user input from the CLI to scaffold a new project.

    This function:
    - Displays available project templates
    - Prompts the user for project metadata (name, version, author)
    - Validates selected template
    - Prompts for storage type and Databricks workspace URL
    - Collects output directory path

    Returns:
        dict: A dictionary containing all user inputs required for project generation.
    """
    typer.echo("\nACC Project Scaffolder\n")

    typer.echo("Available templates:")
    for key, meta in TEMPLATES.items():
        typer.echo(f"  {key:<10} — {meta['description']}")
    typer.echo()

    project_name = typer.prompt("Project name")
    version = typer.prompt("Version", default="0.1.0")
    author = typer.prompt("Author")

    template = typer.prompt(
        f"Template [{' / '.join(TEMPLATES.keys())}]",
        default="etl"
    )

    if template not in TEMPLATES:
        typer.echo(
            f"Unknown template '{template}'. Choose from: {list(TEMPLATES.keys())}",
            err=True
        )
        raise typer.Exit(code=1)

    choices = list(STORAGE_PATHS.keys())

    storage_type = typer.prompt(
        f"Storage [{' / '.join(choices)}]",
        default=choices[0]
    )

    workspace = typer.prompt("Databricks workspace URL")

    output_dir = typer.prompt(
        "Output directory",
        default=str(Path.cwd().parent)
    )

    return {
        "project_name": project_name,
        "version": version,
        "author": author,
        "template": template,
        "storage_type": storage_type.lower(),
        "workspace": workspace,
        "output_dir": output_dir,
    }


# STORAGE
def resolve_storage(storage_type: str) -> str:
    """
    Resolves the physical storage path based on the selected storage type.

    Args:
        storage_type (str): The storage backend selected by the user
            (e.g., 's3', 'dbfs', 'uc', 'adls').

    Returns:
        str: The resolved storage path.

    Raises:
        ValueError: If the provided storage type is not supported.
    """
    storage_type = storage_type.lower()

    if storage_type not in STORAGE_PATHS:
        raise ValueError(
            f"Unsupported storage '{storage_type}'. Choose from: {list(STORAGE_PATHS)}"
        )

    return STORAGE_PATHS[storage_type]


# HELPERS
def generate_slug(name: str) -> str:
    """
    Converts a project name into a filesystem-safe slug.

    Replaces spaces and hyphens with underscores and converts to lowercase.

    Args:
        name (str): Original project name.

    Returns:
        str: Normalized slug suitable for directories or package names.
    """
    return name.replace("-", "_").replace(" ", "_").lower()


# COOKIECUTTER EXECUTION
def generate_project(template_dir: str, output_dir: str, context: dict):
    """
    Generates a project scaffold using a Cookiecutter template.

    Args:
        template_dir (str): Path to the Cookiecutter template directory.
        output_dir (str): Directory where the project will be generated.
        context (dict): Template variables used to render the project.

    Raises:
        RuntimeError: If Cookiecutter execution fails.
    """
    try:
        cookiecutter(
            template_dir,
            no_input=True,
            output_dir=output_dir,
            extra_context=context,
        )
    except Exception as e:
        raise RuntimeError(f"Cookiecutter failed: {e}")


# OUTPUT
def print_summary(project_path: Path, storage: str, name: str, version: str):
    """
    Prints a summary of the generated project and next steps.

    Args:
        project_path (Path): Path where the project was created.
        storage (str): Resolved storage location for artifacts.
        name (str): Project name.
        version (str): Project version.
    """
    typer.echo("\nProject created successfully!\n")
    typer.echo(f"Location:   {project_path.resolve()}")
    typer.echo(f"Storage:    {storage}")
    typer.echo(f"Wheel path: {storage}/{name}-{version}-py3-none-any.whl")

    typer.echo("\nNext steps:")
    typer.echo(f"cd {project_path.resolve()}")
    typer.echo("make install && make test")