"""Core dev commands — lint, test, build, skill-lint (language-aware dispatch)."""

from __future__ import annotations

from pathlib import Path

from afd import CommandResult, error, success

from botcore.config import load_config
from botcore.utils.runner import run_command, run_python_module
from botcore.utils.workspace import find_workspace


async def dev_lint(package: str | None = None, fix: bool = False) -> CommandResult[dict]:
    """Run linting using the configured linter.

    Dispatches to ruff (Python), biome (TypeScript), or clippy (Rust)
    based on the workspace language configuration.
    """
    ws = find_workspace()
    config = load_config(workspace=ws)
    linter = config.linter

    if not linter:
        return error(
            "NO_LINTER",
            "No linter configured and language could not be detected",
            suggestion="Set 'language' in [tool.botcore] config",
        )

    if linter == "ruff":
        args = ["check", "."]
        if fix:
            args.append("--fix")
        result = await run_python_module("ruff", args, cwd=ws)
        fix_cmd = "ruff check . --fix"
    elif linter == "biome":
        args = ["npx", "biome", "check", "."]
        if fix:
            args.append("--write")
        result = await run_command(args, cwd=ws)
        fix_cmd = "npx biome check . --write"
    elif linter == "clippy":
        args = ["cargo", "clippy"]
        if fix:
            args.extend(["--fix", "--allow-dirty"])
        result = await run_command(args, cwd=ws)
        fix_cmd = "cargo clippy --fix"
    else:
        return error("UNKNOWN_LINTER", f"Unknown linter: {linter}")

    if result.get("success"):
        return success(data=result, reasoning="All checks passed")
    output = result.get("output", "")
    error_msg = result.get("error") or output or "Lint failed"
    return error("LINT_FAILED", error_msg, suggestion=f"Run '{fix_cmd}' to auto-fix issues")


async def dev_test(package: str | None = None, coverage: bool = False) -> CommandResult[dict]:
    """Run tests using the configured test runner.

    Dispatches to pytest (Python), vitest (TypeScript), or cargo test (Rust).
    """
    ws = find_workspace()
    config = load_config(workspace=ws)
    test_runner = config.test_runner

    if not test_runner:
        return error(
            "NO_TEST_RUNNER",
            "No test runner configured and language could not be detected",
            suggestion="Set 'language' in [tool.botcore] config",
        )

    if test_runner == "pytest":
        args = []
        if package:
            args.append(f"packages/{package}")
        if coverage:
            args.extend(["--cov", "--cov-report=term-missing"])
        result = await run_python_module("pytest", args, cwd=ws)
        run_cmd = "pytest -v"
    elif test_runner == "vitest":
        args = ["npx", "vitest", "run"]
        if package:
            args.extend(["--project", package])
        result = await run_command(args, cwd=ws)
        run_cmd = "npx vitest run"
    elif test_runner == "cargo-test":
        args = ["cargo", "test"]
        if package:
            args.extend(["-p", package])
        result = await run_command(args, cwd=ws)
        run_cmd = "cargo test"
    else:
        return error("UNKNOWN_TEST_RUNNER", f"Unknown test runner: {test_runner}")

    if result.get("success"):
        return success(data=result, reasoning="All tests passed")
    output = result.get("output", "")
    error_msg = result.get("error") or output or "Tests failed"
    return error("TEST_FAILED", error_msg, suggestion=f"Run '{run_cmd}' locally for details")


async def dev_build(package: str | None = None) -> CommandResult[dict]:
    """Build a package using the language-appropriate build tool."""
    ws = find_workspace()
    config = load_config(workspace=ws)
    language = config.language

    if language == "python":
        if not package:
            return error(
                "PACKAGE_REQUIRED",
                "Package name required for Python build",
                suggestion="Specify a package: botcore dev build <package>",
            )
        pkg_path = ws / "packages" / package if ws else Path(package)
        result = await run_python_module("hatch", ["build"], cwd=pkg_path)
    elif language == "typescript":
        args = ["npx", "turbo", "build"]
        if package:
            args.extend(["--filter", package])
        result = await run_command(args, cwd=ws)
    elif language == "rust":
        args = ["cargo", "build"]
        if package:
            args.extend(["-p", package])
        result = await run_command(args, cwd=ws)
    else:
        return error(
            "NO_LANGUAGE",
            "No language detected for build",
            suggestion="Set 'language' in [tool.botcore] config",
        )

    if result.get("success"):
        return success(data=result)
    return error(
        "BUILD_FAILED",
        result.get("error", "Build failed"),
        suggestion="Check build logs and ensure dependencies are installed",
    )


async def dev_skill_lint() -> CommandResult[dict]:
    """Lint Claude skills for common issues.

    Delegates to the full skill_lint command in botcore.commands.skill.lint.
    """
    from botcore.commands.skill.lint import skill_lint

    return await skill_lint()
