from pathlib import Path
from typing import Annotated, Any

import typer
from rich import print

from cognite_toolkit._cdf_tk.commands import RespaceCommand


class RespaceApp(typer.Typer):
    def __init__(self, *args: Any, **kwargs: Any) -> None:
        super().__init__(*args, **kwargs)
        self.callback(invoke_without_command=True)(self.main)
        self.command("plan")(self.respace_plan)
        self.command("execute")(self.respace_execute)

    @staticmethod
    def main(ctx: typer.Context) -> None:
        """Commands for respacing (moving) nodes between CDF spaces."""
        if ctx.invoked_subcommand is None:
            print("Use [bold yellow]cdf data respace --help[/] for more information.")

    @staticmethod
    def respace_plan(
        csv_file: Annotated[
            Path,
            typer.Argument(
                help="Path to CSV file with nodes to respace. Expected columns: sourceSpace, externalId, targetSpace.",
                exists=True,
                file_okay=True,
                dir_okay=False,
                resolve_path=True,
            ),
        ],
        output_file: Annotated[
            Path,
            typer.Option(
                "--output-file",
                "-o",
                help="Path for the output plan file.",
            ),
        ] = Path("respace_plan.json"),
    ) -> None:
        """Generate a respace plan by analyzing nodes and their dependencies."""
        cmd = RespaceCommand()
        cmd.run(lambda: cmd.plan(csv_file=csv_file, output_file=output_file))

    @staticmethod
    def respace_execute(
        plan_file: Annotated[
            Path,
            typer.Argument(
                help="Path to the respace plan JSON generated by 'plan' command.",
                exists=True,
                file_okay=True,
                dir_okay=False,
                resolve_path=True,
            ),
        ],
        backup_dir: Annotated[
            Path,
            typer.Option(
                "--backup-dir",
                "-b",
                help="Directory to store backup data before migration.",
            ),
        ],
        dry_run: Annotated[
            bool,
            typer.Option(
                "--dry-run",
                "-d",
                help="Preview changes without executing.",
            ),
        ] = False,
    ) -> None:
        """Execute a respace plan, migrating nodes between spaces."""
        cmd = RespaceCommand()
        cmd.run(lambda: cmd.execute(plan_file=plan_file, backup_dir=backup_dir, dry_run=dry_run))
