"""Command line interface for NightShift."""

from __future__ import annotations

import argparse
from pathlib import Path
import sys

from .config import validate_config
from .errors import NightShiftError
from .init import init_project
from .pipeline import PipelineRunner
from .status import build_status, format_status
from .tasks import (
    ensure_dependencies_satisfied,
    parse_task_file,
    select_next_runnable_task,
    select_task_by_id,
    validate_task_dependencies,
)
from .web import create_app


def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(prog="nightshift", description="Auditable AI pipeline runner.")
    parser.add_argument("--version", action="version", version="nightshift 0.1.0")

    subparsers = parser.add_subparsers(dest="command", required=True)

    init_parser = subparsers.add_parser("init", help="Create starter NightShift files.")
    init_parser.add_argument("--root", default=".", help="Directory to initialize.")
    init_parser.add_argument("--force", action="store_true", help="Overwrite existing starter files.")

    validate_parser = subparsers.add_parser("validate", help="Validate nightshift.yaml.")
    validate_parser.add_argument("--config", default="nightshift.yaml", help="Config file to validate.")

    run_parser = subparsers.add_parser("run", help="Run the configured pipeline for one task.")
    run_parser.add_argument("--config", default="nightshift.yaml", help="Config file to use.")
    run_parser.add_argument("--task", help="Specific task id to run.")
    run_parser.add_argument("--all", action="store_true", help="Run all runnable incomplete tasks.")

    status_parser = subparsers.add_parser("status", help="Inspect NightShift project status.")
    status_parser.add_argument("--config", default="nightshift.yaml", help="Config file to inspect.")

    web_parser = subparsers.add_parser("web", help="Start a read-only artifact dashboard.")
    web_parser.add_argument("--config", default="nightshift.yaml", help="Config file to inspect.")
    web_parser.add_argument("--host", default="127.0.0.1", help="Host to bind.")
    web_parser.add_argument("--port", type=int, default=8765, help="Port to bind.")

    return parser


def main(argv: list[str] | None = None) -> int:
    parser = build_parser()
    args = parser.parse_args(argv)

    try:
        if args.command == "init":
            written = init_project(Path(args.root), force=args.force)
            print("Created NightShift starter files:")
            for path in written:
                print(f"- {path}")
            return 0

        if args.command == "validate":
            config = validate_config(args.config)
            tasks = parse_task_file(config.project.root, config.project.task_file)
            validate_task_dependencies(tasks)
            incomplete = sum(1 for task in tasks if not task.completed)
            print(f"Config valid: {config.path}")
            print(f"Project: {config.project.name}")
            print(f"Stages: {len(config.pipeline.stages)}")
            print(f"Tasks: {len(tasks)}")
            print(f"Incomplete tasks: {incomplete}")
            return 0

        if args.command == "run":
            config = validate_config(args.config)
            tasks = parse_task_file(config.project.root, config.project.task_file)
            validate_task_dependencies(tasks)
            if args.all and args.task:
                parser.error("run accepts either --all or --task, not both.")
            runner = PipelineRunner(config)
            if args.all:
                selected = [task for task in tasks if not task.completed]
                result = runner.run_tasks(selected)
                print(f"Status: {result.status}")
                print(f"Tasks run: {len(result.task_results)}")
                print(f"Completed: {result.completed_count}")
                print(f"Failed: {result.failed_count}")
                print(f"Reason: {result.reason}")
                return 0 if result.status == "complete" else 1

            task = select_task_by_id(tasks, args.task) if args.task else select_next_runnable_task(tasks)
            ensure_dependencies_satisfied(tasks, task)
            result = runner.run_task(task)
            print(f"Task: {result.task_id}")
            print(f"Status: {result.status}")
            print(f"Retries: {result.retry_count}")
            print(f"Artifacts: {result.artifact_dir}")
            print(f"Reason: {result.reason}")
            return 0 if result.status == "complete" else 1

        if args.command == "status":
            config = validate_config(args.config)
            tasks = parse_task_file(config.project.root, config.project.task_file)
            print(format_status(build_status(config, tasks)))
            return 0

        if args.command == "web":
            config = validate_config(args.config)
            app = create_app(config.project.root, config.project.artifact_dir)
            app.run(host=args.host, port=args.port)
            return 0

    except NightShiftError as exc:
        print(str(exc), file=sys.stderr)
        return 1

    return 0


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