from __future__ import annotations

import json
import re
import shutil
import sys
from importlib import metadata
from pathlib import Path


def get_cli_version() -> str:
    package_json_version = _find_package_json_version()
    if package_json_version:
        return package_json_version
    try:
        return metadata.version("qingflow-mcp")
    except metadata.PackageNotFoundError:
        return "0+local"


def get_cli_version_info() -> dict[str, str | None]:
    package_root = _find_package_root()
    return {
        "version": get_cli_version(),
        "package": _find_package_name(package_root) or "@qingflow-tech/qingflow-cli",
        "executable_path": _resolve_executable_path(),
        "command_path": shutil.which("qingflow"),
        "package_root": str(package_root) if package_root is not None else None,
        "skill_version": _find_skill_version(package_root),
    }


def _find_package_json_version() -> str | None:
    package_root = _find_package_root()
    if package_root is None:
        return None
    try:
        payload = json.loads((package_root / "package.json").read_text(encoding="utf-8"))
    except (OSError, json.JSONDecodeError):
        return None
    version = str(payload.get("version") or "")
    return version or None


def _find_package_root() -> Path | None:
    current = Path(__file__).resolve()
    for parent in current.parents:
        package_json = parent / "package.json"
        if not package_json.exists():
            continue
        try:
            payload = json.loads(package_json.read_text(encoding="utf-8"))
        except (OSError, json.JSONDecodeError):
            continue
        name = str(payload.get("name") or "")
        version = str(payload.get("version") or "")
        if version and name in {
            "qingflow-mcp-workspace",
            "@qingflow-tech/qingflow-cli",
            "@qingflow-tech/qingflow-app-user-mcp",
            "@qingflow-tech/qingflow-app-builder-mcp",
            "@josephyan/qingflow-cli",
            "@josephyan/qingflow-app-user-mcp",
            "@josephyan/qingflow-app-builder-mcp",
        }:
            return parent
    return None


def _find_package_name(package_root: Path | None) -> str | None:
    if package_root is None:
        return None
    try:
        payload = json.loads((package_root / "package.json").read_text(encoding="utf-8"))
    except (OSError, json.JSONDecodeError):
        return None
    name = str(payload.get("name") or "")
    return name or None


def _resolve_executable_path() -> str | None:
    if not sys.argv:
        return None
    raw = str(sys.argv[0] or "").strip()
    if not raw:
        return None
    try:
        return str(Path(raw).resolve())
    except OSError:
        return raw


def _find_skill_version(package_root: Path | None) -> str | None:
    if package_root is None:
        return None
    candidates = [
        package_root / "skills" / "qingflow-cli" / "SKILL.md",
        package_root / "skill" / "qingflow-cli" / "SKILL.md",
    ]
    for skill_file in candidates:
        if not skill_file.exists():
            continue
        try:
            text = skill_file.read_text(encoding="utf-8")
        except OSError:
            continue
        match = re.search(r"Skill\s*版本\**[:：]\s*`?([^`\s）)]+)", text)
        if match:
            return match.group(1).strip()
    return None
