import sys

from mixersystem import __version__
from mixersystem.data.repository import parse_args, run_cli
from mixersystem.sync import sync
from mixersystem.workflows.work.create_work import run as run_create_work
from mixersystem.workflows.plan.create_plan import run as run_create_plan
from mixersystem.workflows.task.create_task import run as run_create_task
from mixersystem.workflows.update.create_update import run as run_create_update
from mixersystem.workflows.upgrade.create_upgrade import run as run_create_upgrade

_WORKFLOWS = {
    "task": run_create_task,
    "plan": run_create_plan,
    "work": run_create_work,
    "update": run_create_update,
    "upgrade": run_create_upgrade,
}


def _print_usage() -> None:
    print(
        "Usage:\n"
        "  python3 -m mixersystem --help\n"
        "  python3 -m mixersystem --version\n"
        "  python3 -m mixersystem init [--project_root=<path>]\n"
        "  python3 -m mixersystem sync [--project_root=<path>]\n"
        "  python3 -m mixersystem run <task|plan|work|update|upgrade> --work_folder=<path> [--key=value...]\n"
        "\n"
        "Compatibility aliases:\n"
        "  python3 -m mixersystem create-task --work_folder=<path> [--key=value...]\n"
        "  python3 -m mixersystem create-plan --work_folder=<path> [--key=value...]\n"
        "  python3 -m mixersystem create-work --work_folder=<path> [--key=value...]\n"
        "  python3 -m mixersystem create-update --work_folder=<path> [--key=value...]\n"
        "  python3 -m mixersystem create-upgrade --work_folder=<path> [--key=value...]\n"
    )


def _run_workflow(run_fn, args: list[str]) -> int:
    original_argv = sys.argv
    try:
        sys.argv = [original_argv[0], *args]
        run_cli(run_fn)
    finally:
        sys.argv = original_argv
    return 0


def _parse_root_only_args(args: list[str], command_name: str) -> tuple[str | None, int]:
    parsed = parse_args(args)
    project_root = parsed.pop("project_root", None)
    if parsed:
        unknown = ", ".join(sorted(parsed.keys()))
        print(f"Unsupported {command_name} arguments: {unknown}")
        return None, 1
    return project_root, 0


def _run_sync(args: list[str]) -> int:
    project_root, err = _parse_root_only_args(args, "sync")
    if err:
        return err
    sync(project_root=project_root)
    return 0


def _run_init(args: list[str]) -> int:
    project_root, err = _parse_root_only_args(args, "init")
    if err:
        return err
    sync(project_root=project_root)
    target = project_root or "."
    print(f"Initialized MixerSystem runtime in {target}")
    return 0


def _run_named_workflow(workflow_name: str, args: list[str]) -> int:
    run_fn = _WORKFLOWS.get(workflow_name)
    if not run_fn:
        allowed = ", ".join(sorted(_WORKFLOWS.keys()))
        print(f"Unknown workflow: {workflow_name}. Supported workflows: {allowed}")
        return 1
    return _run_workflow(run_fn, args)


def main(argv: list[str] | None = None) -> int:
    args = list(sys.argv[1:] if argv is None else argv)
    if not args or args[0] in {"-h", "--help"}:
        _print_usage()
        return 0

    command = args[0]
    command_args = args[1:]

    if command in {"-V", "--version", "version"}:
        print(__version__)
        return 0

    if command == "init":
        return _run_init(command_args)
    if command == "sync":
        return _run_sync(command_args)

    if command == "run":
        if not command_args:
            print("Usage: python3 -m mixersystem run <task|plan|work|update|upgrade> --work_folder=<path> [--key=value...]")
            return 1
        workflow_name = command_args[0]
        workflow_args = command_args[1:]
        return _run_named_workflow(workflow_name, workflow_args)

    if command == "create-task":
        return _run_named_workflow("task", command_args)
    if command == "create-plan":
        return _run_named_workflow("plan", command_args)
    if command == "create-work":
        return _run_named_workflow("work", command_args)
    if command == "create-update":
        return _run_named_workflow("update", command_args)
    if command == "create-upgrade":
        return _run_named_workflow("upgrade", command_args)

    if command in _WORKFLOWS:
        return _run_named_workflow(command, command_args)

    print(f"Unknown command: {command}")
    _print_usage()
    return 1


if __name__ == "__main__":
    raise SystemExit(main())
