"""
Onboarding flow for first-time CLI users.

Three-question profile-based onboarding: role → language → career direction.
Registers the user with the API and persists the resulting config.

Run via: skilark setup
"""

import uuid as _uuid_module

from InquirerPy import inquirer
from rich.console import Console

from skilark_cli.client import SkilarkClient
from skilark_cli.config_store import ConfigStore

ROLE_CHOICES = [
    {"name": "Software Engineer", "value": "swe"},
    {"name": "ML / AI Engineer", "value": "ai_ml"},
    {"name": "Data Engineer", "value": "data_eng"},
    {"name": "Platform / DevOps", "value": "platform"},
    {"name": "Security Engineer", "value": "security"},
    {"name": "Product Manager", "value": "product"},
    {"name": "Research", "value": "research"},
    {"name": "Other", "value": "other"},
]

LANGUAGE_CHOICES = [
    {"name": "Python", "value": "Python"},
    {"name": "Go", "value": "Go"},
    {"name": "Java", "value": "Java"},
    {"name": "TypeScript", "value": "TypeScript"},
    {"name": "Rust", "value": "Rust"},
    {"name": "C++", "value": "C++"},
    {"name": "Other", "value": "Other"},
]

DIRECTION_CHOICES = [
    {"name": "Stay sharp in my current role", "value": "stay_sharp"},
    {"name": "Level up (promotion track)", "value": "level_up"},
    {"name": "Transition to a new role", "value": "transition"},
]

# Mapping from profile fields to auto-derived topics for backward compat.
_LANGUAGE_TO_TOPICS: dict[str, list[str]] = {
    "Python": ["python"],
    "Go": ["go"],
    "Java": ["java"],
    "TypeScript": ["typescript"],
    "Rust": ["rust"],
    "C++": ["c"],
    "Other": [],
}

_ROLE_TO_TOPICS: dict[str, list[str]] = {
    "swe": ["dsa", "system-design"],
    "ai_ml": ["pytorch", "llms", "python"],
    "data_eng": ["sql", "spark", "python"],
    "platform": ["kubernetes", "docker", "terraform"],
    "security": ["linux"],
    "product": [],
    "research": ["python"],
    "other": [],
}

# Keep old TOPIC_CHOICES available for backward-compat (imported by tests etc.)
TOPIC_CHOICES = [
    {"name": "Python", "value": "python"},
    {"name": "Java", "value": "java"},
    {"name": "JavaScript", "value": "javascript"},
    {"name": "Go", "value": "go"},
    {"name": "Rust", "value": "rust"},
    {"name": "C / C++", "value": "c"},
    {"name": "TypeScript", "value": "typescript"},
    {"name": "SQL", "value": "sql"},
    {"name": "Kubernetes", "value": "kubernetes"},
    {"name": "Docker", "value": "docker"},
    {"name": "Terraform", "value": "terraform"},
    {"name": "AWS", "value": "aws"},
    {"name": "CI/CD", "value": "cicd"},
    {"name": "Linux", "value": "linux"},
    {"name": "Spark", "value": "spark"},
    {"name": "Kafka", "value": "kafka"},
    {"name": "Airflow", "value": "airflow"},
    {"name": "Data Modeling", "value": "data-modeling"},
    {"name": "PyTorch", "value": "pytorch"},
    {"name": "LLMs", "value": "llms"},
    {"name": "Deep Learning", "value": "deep-learning"},
    {"name": "Machine Learning", "value": "machine-learning"},
    {"name": "REST APIs", "value": "rest-api"},
    {"name": "Redis", "value": "redis"},
    {"name": "Spring Boot", "value": "spring-boot"},
    {"name": "Distributed Systems", "value": "distributed-systems"},
    {"name": "DSA", "value": "dsa"},
    {"name": "Design Patterns", "value": "patterns"},
    {"name": "System Design", "value": "system-design"},
    {"name": "Git", "value": "git"},
    {"name": "Maven", "value": "maven"},
    {"name": "Bazel", "value": "bazel"},
]


def derive_topics(role: str, language: str) -> list[str]:
    """Derive backward-compatible topics from profile fields."""
    topics = list(_LANGUAGE_TO_TOPICS.get(language, []))
    for t in _ROLE_TO_TOPICS.get(role, []):
        if t not in topics:
            topics.append(t)
    return topics if topics else ["python"]  # fallback


def run_onboarding(config_store: ConfigStore, api_url: str) -> None:
    """Run the interactive first-time setup flow.

    Three questions: role → language → career direction.
    Registers the user via the API and writes the resulting config to disk.

    Args:
        config_store: Where to persist the user config after setup.
        api_url:      Base URL of the Skilark API to register against.
    """
    console = Console()
    console.print("\n[bold]Welcome to Skilark.[/bold] Let's set up your profile.\n")

    # 1. Current role
    current_role = inquirer.select(
        message="What's your current role?",
        choices=ROLE_CHOICES,
    ).execute()

    # 2. Primary language
    primary_language = inquirer.select(
        message="What's your primary programming language?",
        choices=LANGUAGE_CHOICES,
    ).execute()

    # 3. Career direction
    career_direction = inquirer.select(
        message="What's your career direction?",
        choices=DIRECTION_CHOICES,
    ).execute()

    # 3b. If transitioning, ask target role
    target_role = None
    if career_direction == "transition":
        target_role = inquirer.select(
            message="What role do you want to transition to?",
            choices=[c for c in ROLE_CHOICES if c["value"] != current_role],
        ).execute()

    # Derive topics for backward compat with challenge selection
    topics = derive_topics(current_role, primary_language)

    # If DSA is in the derived topics, ask coding language preference
    coding_language = None
    if "dsa" in topics:
        coding_language = inquirer.select(
            message="Solve coding problems in:",
            choices=[
                {"name": "Python", "value": "python"},
                {"name": "Java", "value": "java"},
                {"name": "Skip (knowledge challenges only)", "value": None},
            ],
            default="python",
        ).execute()

    client = SkilarkClient(base_url=api_url)
    user = client.create_user(
        topics=topics,
        current_role=current_role,
        primary_language=primary_language,
        career_direction=career_direction,
        target_role=target_role,
    )

    user_id: str = user["id"]
    try:
        _uuid_module.UUID(user_id)
    except (ValueError, AttributeError, TypeError) as exc:
        raise ValueError(f"API returned an invalid user_id: {user_id!r}") from exc

    config_store.save(user_id=user_id, topics=topics, api_url=api_url)
    config_store.update_profile(
        current_role=current_role,
        primary_language=primary_language,
        career_direction=career_direction,
    )

    if coding_language:
        config_store.update_coding_language(coding_language)

    console.print(f"\n[green]✓[/green] Profile set. Let's go.\n")


def run_profile_migration(config_store: ConfigStore, api_url: str) -> None:
    """Run the profile migration flow for existing users without a profile.

    Asks the 3 profile questions and updates the API + local config.

    Args:
        config_store: Where the config is persisted.
        api_url:      Base URL of the Skilark API.
    """
    console = Console()
    console.print(
        "\n[bold]We've updated![/bold] Set up your profile for better recommendations.\n"
    )

    current_role = inquirer.select(
        message="What's your current role?",
        choices=ROLE_CHOICES,
    ).execute()

    primary_language = inquirer.select(
        message="What's your primary programming language?",
        choices=LANGUAGE_CHOICES,
    ).execute()

    career_direction = inquirer.select(
        message="What's your career direction?",
        choices=DIRECTION_CHOICES,
    ).execute()

    config = config_store.load()
    user_id = config["user_id"]

    # Re-derive topics from new profile for backward compat with challenge selection.
    topics = derive_topics(current_role, primary_language)

    client = SkilarkClient(base_url=api_url, user_id=user_id)
    client.update_profile(
        current_role=current_role,
        primary_language=primary_language,
        career_direction=career_direction,
    )
    client.update_topics(topics)

    config_store.update_topics(topics)
    config_store.update_profile(
        current_role=current_role,
        primary_language=primary_language,
        career_direction=career_direction,
    )

    console.print("\n[green]✓[/green] Profile updated.\n")
