import typer
from typing import Optional
from pathlib import Path
from rich.console import Console
from sibi_flux.init.core import initialize_project

app = typer.Typer(help="Sibi Flux CLI")
console = Console()


@app.callback()
def callback():
    """
    Sibi Flux CLI
    """


@app.command()
def init(
    project_name: str = typer.Argument(..., help="Name of the project to create"),
    lib: bool = typer.Option(
        False, "--lib", help="Initialize as a library project (passed to uv init)"
    ),
    app: bool = typer.Option(
        False, "--app", help="Initialize as an application project (passed to uv init)"
    ),
):
    """
    Initialize a new Sibi Flux project.

    Creates a new directory <project_name>, initializes it with 'uv',
    and adds 'sibi-flux' as a dependency.
    """
    initialize_project(project_name, lib, app)


@app.command()
def create_app(
    name: str = typer.Argument(..., help="Name of the application to create"),
):
    """
    Create a new application within an existing Sibi Flux project.
    
    Generates standard directory structure in `<project_root>/<name>`.
    """
    from sibi_flux.init.app import init_app
    init_app(name)


@app.command()
def create_cubes(
    app_name: str = typer.Argument(..., help="Name of the application"),
    force: bool = typer.Option(False, "--force", "-f", help="Force overwrite of existing files"),
):
    """
    Generate app-specific Datacube extensions from `<app_name>/datacubes/datacubes.yaml`.
    """
    from sibi_flux.init.cube_extender import create_cubes
    create_cubes(app_name, force=force)


@app.command()
def propose_cubes(
    db_domain: str = typer.Argument(..., help="Database domain to filter by (e.g., 'ibis_dev')"),
    app_name: str = typer.Argument(..., help="Name of the target application"),
    force: bool = typer.Option(False, "--force", "-f", help="Force overwrite of existing configuration"),
):
    """
    Scan global registry for datacubes in <db_domain> and add them to <app_name>/datacubes/datacubes.yaml.
    """
    from sibi_flux.init.cube_proposer import propose_cubes
    propose_cubes(db_domain, app_name, force=force)


@app.command()
def env(
    project_path: Path = typer.Argument(Path("."), help="Project root directory"),
    env_file: Optional[Path] = typer.Option(
        None, "--env-file", "-e", help="Path to environment file (defaults to .env)"
    ),
    cleanup: bool = typer.Option(
        False, "--cleanup", help="Remove existing configuration files"
    ),
    production: bool = typer.Option(
        False,
        "--production",
        "-p",
        help="Generate production skeleton (no hardcoded values)",
    ),
    settings: bool = typer.Option(True, "--settings/--no-settings", help="Run settings.py generation"),
    creds: bool = typer.Option(True, "--creds/--no-creds", help="Run credentials generation"),
    discover: bool = typer.Option(True, "--discover/--no-discover", help="Run host discovery"),
    infra: bool = typer.Option(True, "--infra/--no-infra", help="Run infrastructure code generation"),
):
    """
    Initialize configuration files (settings.py, credentials) based on .env
    """
    from sibi_flux.init.env import init_env

    init_env(
        project_path, 
        env_file, 
        cleanup=cleanup, 
        production_mode=production,
        run_settings=settings,
        run_creds=creds,
        run_discover=discover,
        run_infra=infra
    )


# Mount Sub-commands
from sibi_flux.datacube.cli import app as dc_app
from sibi_flux.init.config_cli import app as config_app

app.add_typer(dc_app, name="dc", help="Datacube generation and management commands")
app.add_typer(config_app, name="config", help="Configuration management commands")


if __name__ == "__main__":
    app()
