"""GitHub authentication — gh CLI detection + PAT token fallback."""

from __future__ import annotations

import shutil
import subprocess
from pathlib import Path

from ievo.core.credentials import set_credential
from ievo.core.global_config import set_config
from ievo.utils.console import info, step, success, warn


def check_gh_cli() -> bool:
    """Check if gh CLI is installed."""
    return shutil.which("gh") is not None


def check_gh_auth() -> str | None:
    """Check if gh CLI is authenticated. Returns username or None."""
    if not check_gh_cli():
        return None
    try:
        result = subprocess.run(
            ["gh", "auth", "status"],
            capture_output=True,
            text=True,
            check=False,
        )
        if result.returncode == 0:
            # Parse username from output like "Logged in to github.com account denis"
            for line in result.stderr.splitlines():
                if "account" in line.lower():
                    parts = line.strip().split()
                    # Find word after "account"
                    for i, word in enumerate(parts):
                        if word.lower() == "account" and i + 1 < len(parts):
                            return parts[i + 1].strip("()")
            return "unknown"
    except FileNotFoundError:
        pass
    return None


def prompt_github_auth(home: Path) -> str | None:
    """Interactive GitHub auth flow. Returns auth method or None.

    Returns:
        "gh_cli" — using gh CLI auth
        "pat" — stored PAT token
        None — skipped
    """
    info("[bold]GitHub authentication[/bold]")

    # 1. Check if gh CLI is available and authenticated
    if check_gh_cli():
        username = check_gh_auth()
        if username:
            success(f"GitHub CLI authenticated ([bold]{username}[/bold])")
            set_config(home, "github_auth", "gh_cli")
            return "gh_cli"

        # gh is installed but not authenticated
        step("GitHub CLI found but not authenticated")
        answer = input("  Run 'gh auth login' now? (Y/n): ").strip().lower()
        if answer in ("", "y", "yes"):
            try:
                subprocess.run(["gh", "auth", "login"], check=False)
                username = check_gh_auth()
                if username:
                    success(f"GitHub CLI authenticated ([bold]{username}[/bold])")
                    set_config(home, "github_auth", "gh_cli")
                    return "gh_cli"
            except FileNotFoundError:
                pass
            warn("gh auth login did not complete")

    else:
        step("GitHub CLI (gh) not found")

    # 2. Fallback: ask for PAT
    info("Enter a GitHub Personal Access Token (or press Enter to skip):")
    step("Create one at: https://github.com/settings/tokens")
    token = input("  GitHub PAT: ").strip()

    if not token:
        warn("Skipped. GitHub features (PRs, issues) won't work until configured.")
        info("Run [bold]ievo config set GITHUB_TOKEN <token>[/bold] later.")
        return None

    set_credential(home, "GITHUB_TOKEN", token)
    set_config(home, "github_auth", "pat")
    success("GitHub token saved (encrypted)")
    return "pat"


def get_github_token(home: Path) -> str | None:
    """Get GitHub token from gh CLI or encrypted credentials."""
    from ievo.core.global_config import get_config

    auth_method = get_config(home, "github_auth")

    if auth_method == "gh_cli":
        try:
            result = subprocess.run(
                ["gh", "auth", "token"],
                capture_output=True,
                text=True,
                check=True,
            )
            return result.stdout.strip()
        except (FileNotFoundError, subprocess.CalledProcessError):
            return None

    if auth_method == "pat":
        from ievo.core.credentials import get_credential

        return get_credential(home, "GITHUB_TOKEN")

    return None
