"""Authentication commands for Hanzo CLI."""

import os
import json
from typing import Optional
from pathlib import Path
from datetime import datetime

import click
from rich import box
from rich.panel import Panel
from rich.table import Table
from rich.prompt import Prompt

from ..utils.output import console


class AuthManager:
    """Manage Hanzo authentication."""

    def __init__(self):
        self.config_dir = Path.home() / ".hanzo"
        self.auth_file = self.config_dir / "auth.json"

    def load_auth(self) -> dict:
        """Load authentication data."""
        if self.auth_file.exists():
            try:
                return json.loads(self.auth_file.read_text())
            except Exception:
                pass
        return {}

    def save_auth(self, auth: dict):
        """Save authentication data."""
        self.config_dir.mkdir(exist_ok=True)
        self.auth_file.write_text(json.dumps(auth, indent=2))

    def is_authenticated(self) -> bool:
        """Check if authenticated."""
        if os.getenv("HANZO_API_KEY"):
            return True
        auth = self.load_auth()
        return bool(auth.get("api_key") or auth.get("logged_in"))

    def get_api_key(self) -> Optional[str]:
        """Get API key."""
        if os.getenv("HANZO_API_KEY"):
            return os.getenv("HANZO_API_KEY")
        auth = self.load_auth()
        return auth.get("api_key")


@click.group(name="auth")
def auth_group():
    """Manage Hanzo authentication."""
    pass


@auth_group.command()
@click.option("--email", "-e", help="Email address")
@click.option("--password", "-p", help="Password (not recommended, use prompt)")
@click.option("--api-key", "-k", help="API key for direct authentication")
@click.option("--sso", is_flag=True, help="Use SSO authentication")
@click.pass_context
def login(ctx, email: str, password: str, api_key: str, sso: bool):
    """Login to Hanzo AI."""
    auth_mgr = AuthManager()

    # Check if already authenticated
    if auth_mgr.is_authenticated():
        console.print("[yellow]Already authenticated[/yellow]")
        auth = auth_mgr.load_auth()
        if auth.get("email"):
            console.print(f"Logged in as: {auth['email']}")
        return

    try:
        if api_key:
            # Direct API key authentication
            console.print("Authenticating with API key...")
            auth = {
                "api_key": api_key,
                "logged_in": True,
                "last_login": datetime.now().isoformat(),
            }
            auth_mgr.save_auth(auth)
            console.print("[green]✓[/green] Successfully authenticated with API key")

        elif sso:
            # SSO authentication via browser
            console.print("Opening browser for SSO login...")
            console.print("If browser doesn't open, visit: https://iam.hanzo.ai/login")

            # Try using hanzoai if available
            try:
                from hanzoai.auth import HanzoAuth

                # SSO requires browser flow - not available in CLI
                console.print("[yellow]SSO authentication requires browser[/yellow]")
                console.print("[dim]Use: hanzo auth login --api-key YOUR_KEY[/dim]")
                return
            except ImportError:
                console.print("[yellow]SSO requires hanzoai package[/yellow]")
                console.print("Install with: pip install hanzoai")

        else:
            # Email/password authentication
            if not email:
                email = Prompt.ask("Email")
            if not password:
                password = Prompt.ask("Password", password=True)

            console.print("Authenticating...")

            # Try using hanzoai if available
            try:
                from hanzoai.auth import HanzoAuth

                # Store credentials locally (API validates on first use)
                _ = HanzoAuth  # Validate import

                auth = {
                    "email": email,
                    "logged_in": True,
                    "last_login": datetime.now().isoformat(),
                }
                auth_mgr.save_auth(auth)
                console.print(f"[green]✓[/green] Logged in as {email}")
            except ImportError:
                # Fallback to saving credentials locally
                auth = {
                    "email": email,
                    "logged_in": True,
                    "last_login": datetime.now().isoformat(),
                }
                auth_mgr.save_auth(auth)
                console.print(f"[green]✓[/green] Credentials saved for {email}")

    except Exception as e:
        console.print(f"[red]Login failed: {e}[/red]")


@auth_group.command()
@click.pass_context
def logout(ctx):
    """Logout from Hanzo AI."""
    auth_mgr = AuthManager()

    if not auth_mgr.is_authenticated():
        console.print("[yellow]Not logged in[/yellow]")
        return

    try:
        # Try using hanzoai if available
        try:
            from hanzoai.auth import HanzoAuth
            _ = HanzoAuth  # Available for future remote logout
        except ImportError:
            pass  # Local-only auth

        # Clear local auth
        auth_mgr.save_auth({})

        console.print("[green]✓[/green] Logged out successfully")

    except Exception as e:
        console.print(f"[red]Logout failed: {e}[/red]")


@auth_group.command()
@click.pass_context
def status(ctx):
    """Show authentication status."""
    auth_mgr = AuthManager()

    # Create status table
    table = Table(title="Authentication Status", box=box.ROUNDED)
    table.add_column("Property", style="cyan")
    table.add_column("Value", style="white")

    if auth_mgr.is_authenticated():
        auth = auth_mgr.load_auth()

        table.add_row("Status", "✅ Authenticated")

        # Show auth method
        if os.getenv("HANZO_API_KEY"):
            table.add_row("Method", "Environment Variable")
            api_key = os.getenv("HANZO_API_KEY")
            table.add_row("API Key", f"{api_key[:8]}...{api_key[-4:]}")
        elif auth.get("api_key"):
            table.add_row("Method", "API Key")
            table.add_row("API Key", f"{auth['api_key'][:8]}...")
        elif auth.get("email"):
            table.add_row("Method", "Email/Password")
            table.add_row("Email", auth["email"])

        if auth.get("last_login"):
            table.add_row("Last Login", auth["last_login"])

    else:
        table.add_row("Status", "❌ Not authenticated")
        table.add_row("Action", "Run 'hanzo auth login' to authenticate")

    console.print(table)


@auth_group.command()
def whoami():
    """Show current user information."""
    auth_mgr = AuthManager()

    if not auth_mgr.is_authenticated():
        console.print("[yellow]Not logged in[/yellow]")
        console.print("[dim]Run 'hanzo auth login' to authenticate[/dim]")
        return

    auth = auth_mgr.load_auth()

    # Create user info panel
    lines = []

    if auth.get("email"):
        lines.append(f"[cyan]Email:[/cyan] {auth['email']}")

    if os.getenv("HANZO_API_KEY"):
        lines.append("[cyan]API Key:[/cyan] Set via environment")
    elif auth.get("api_key"):
        lines.append(f"[cyan]API Key:[/cyan] {auth['api_key'][:8]}...")

    if auth.get("last_login"):
        lines.append(f"[cyan]Last Login:[/cyan] {auth['last_login']}")

    content = "\n".join(lines) if lines else "[dim]No user information available[/dim]"

    console.print(
        Panel(content, title="[bold cyan]User Information[/bold cyan]", box=box.ROUNDED)
    )


@auth_group.command(name="set-key")
@click.argument("api_key")
def set_key(api_key: str):
    """Set API key for authentication."""
    auth_mgr = AuthManager()

    auth = auth_mgr.load_auth()
    auth["api_key"] = api_key
    auth["logged_in"] = True
    auth["last_login"] = datetime.now().isoformat()

    auth_mgr.save_auth(auth)

    console.print("[green]✓[/green] API key saved successfully")
    console.print("[dim]You can now use Hanzo Cloud services[/dim]")


# ============================================================================
# API Keys Management
# ============================================================================

@auth_group.group()
def keys():
    """Manage API keys."""
    pass


@keys.command(name="list")
def keys_list():
    """List all API keys."""
    auth_mgr = AuthManager()
    if not auth_mgr.is_authenticated():
        console.print("[yellow]Not authenticated. Run 'hanzo auth login' first.[/yellow]")
        return

    table = Table(title="API Keys", box=box.ROUNDED)
    table.add_column("Name", style="cyan")
    table.add_column("Key", style="white")
    table.add_column("Scopes", style="dim")
    table.add_column("Created", style="dim")
    table.add_column("Last Used", style="dim")

    # Load keys from auth data
    auth = auth_mgr.load_auth()
    api_keys = auth.get("keys", [])

    if not api_keys:
        console.print("[dim]No API keys found. Create one with 'hanzo auth keys create'[/dim]")
        return

    for key in api_keys:
        table.add_row(
            key.get("name", "default"),
            f"{key.get('key', '')[:12]}...",
            ", ".join(key.get("scopes", ["all"])),
            key.get("created", "-"),
            key.get("last_used", "Never"),
        )

    console.print(table)


@keys.command(name="create")
@click.option("--name", "-n", prompt=True, help="Key name")
@click.option("--scopes", "-s", default="all", help="Comma-separated scopes")
def keys_create(name: str, scopes: str):
    """Create a new API key."""
    import secrets

    auth_mgr = AuthManager()
    if not auth_mgr.is_authenticated():
        console.print("[yellow]Not authenticated. Run 'hanzo auth login' first.[/yellow]")
        return

    # Generate a new API key
    new_key = f"hz_{secrets.token_urlsafe(32)}"

    auth = auth_mgr.load_auth()
    if "keys" not in auth:
        auth["keys"] = []

    auth["keys"].append({
        "name": name,
        "key": new_key,
        "scopes": scopes.split(","),
        "created": datetime.now().isoformat(),
        "last_used": None,
    })

    auth_mgr.save_auth(auth)

    console.print(f"[green]✓[/green] API key '{name}' created")
    console.print()
    console.print("[yellow]Save this key - it won't be shown again:[/yellow]")
    console.print(Panel(new_key, border_style="green"))


@keys.command(name="delete")
@click.argument("name")
def keys_delete(name: str):
    """Delete an API key."""
    auth_mgr = AuthManager()

    auth = auth_mgr.load_auth()
    keys = auth.get("keys", [])

    original_len = len(keys)
    auth["keys"] = [k for k in keys if k.get("name") != name]

    if len(auth["keys"]) == original_len:
        console.print(f"[yellow]Key '{name}' not found[/yellow]")
        return

    auth_mgr.save_auth(auth)
    console.print(f"[green]✓[/green] API key '{name}' deleted")


@keys.command(name="rotate")
@click.argument("name")
def keys_rotate(name: str):
    """Rotate an API key."""
    import secrets

    auth_mgr = AuthManager()

    auth = auth_mgr.load_auth()
    keys = auth.get("keys", [])

    for key in keys:
        if key.get("name") == name:
            new_key = f"hz_{secrets.token_urlsafe(32)}"
            key["key"] = new_key
            key["created"] = datetime.now().isoformat()
            auth_mgr.save_auth(auth)

            console.print(f"[green]✓[/green] API key '{name}' rotated")
            console.print()
            console.print("[yellow]New key (save it now):[/yellow]")
            console.print(Panel(new_key, border_style="green"))
            return

    console.print(f"[yellow]Key '{name}' not found[/yellow]")


# ============================================================================
# Organizations Management
# ============================================================================

@auth_group.group()
def orgs():
    """Manage organizations."""
    pass


@orgs.command(name="list")
def orgs_list():
    """List organizations you belong to."""
    auth_mgr = AuthManager()
    if not auth_mgr.is_authenticated():
        console.print("[yellow]Not authenticated[/yellow]")
        return

    auth = auth_mgr.load_auth()
    organizations = auth.get("orgs", [])

    table = Table(title="Organizations", box=box.ROUNDED)
    table.add_column("Name", style="cyan")
    table.add_column("ID", style="dim")
    table.add_column("Role", style="green")
    table.add_column("Current", style="yellow")

    current_org = auth.get("current_org")

    if not organizations:
        # Show default personal org
        table.add_row("Personal", "personal", "Owner", "●" if not current_org else "")
    else:
        for org in organizations:
            is_current = org.get("id") == current_org
            table.add_row(
                org.get("name", ""),
                org.get("id", "")[:12] + "...",
                org.get("role", "Member"),
                "●" if is_current else "",
            )

    console.print(table)


@orgs.command(name="create")
@click.option("--name", "-n", prompt=True, help="Organization name")
def orgs_create(name: str):
    """Create a new organization."""
    import secrets

    auth_mgr = AuthManager()
    if not auth_mgr.is_authenticated():
        console.print("[yellow]Not authenticated[/yellow]")
        return

    org_id = f"org_{secrets.token_hex(8)}"

    auth = auth_mgr.load_auth()
    if "orgs" not in auth:
        auth["orgs"] = []

    auth["orgs"].append({
        "id": org_id,
        "name": name,
        "role": "Owner",
        "created": datetime.now().isoformat(),
    })

    auth_mgr.save_auth(auth)

    console.print(f"[green]✓[/green] Organization '{name}' created")
    console.print(f"[dim]ID: {org_id}[/dim]")


@orgs.command(name="switch")
@click.argument("org_id")
def orgs_switch(org_id: str):
    """Switch to a different organization."""
    auth_mgr = AuthManager()

    auth = auth_mgr.load_auth()
    orgs = auth.get("orgs", [])

    # Find matching org
    matched = next((o for o in orgs if o.get("id") == org_id or o.get("name") == org_id), None)

    if not matched and org_id not in ("personal", "default"):
        console.print(f"[yellow]Organization '{org_id}' not found[/yellow]")
        return

    auth["current_org"] = matched.get("id") if matched else None
    auth_mgr.save_auth(auth)

    org_name = matched.get("name") if matched else "Personal"
    console.print(f"[green]✓[/green] Switched to organization: {org_name}")


@orgs.command(name="delete")
@click.argument("org_id")
def orgs_delete(org_id: str):
    """Delete an organization."""
    from rich.prompt import Confirm

    if not Confirm.ask(f"[red]Delete organization {org_id}? This cannot be undone.[/red]"):
        return

    auth_mgr = AuthManager()
    auth = auth_mgr.load_auth()

    original_len = len(auth.get("orgs", []))
    auth["orgs"] = [o for o in auth.get("orgs", []) if o.get("id") != org_id and o.get("name") != org_id]

    if len(auth.get("orgs", [])) == original_len:
        console.print(f"[yellow]Organization '{org_id}' not found[/yellow]")
        return

    # Reset current org if deleted
    if auth.get("current_org") == org_id:
        auth["current_org"] = None

    auth_mgr.save_auth(auth)
    console.print(f"[green]✓[/green] Organization deleted")


# ============================================================================
# Teams Management
# ============================================================================

@auth_group.group()
def teams():
    """Manage teams within organizations."""
    pass


@teams.command(name="list")
def teams_list():
    """List teams in current organization."""
    auth_mgr = AuthManager()
    if not auth_mgr.is_authenticated():
        console.print("[yellow]Not authenticated[/yellow]")
        return

    auth = auth_mgr.load_auth()
    current_org = auth.get("current_org", "personal")
    teams_data = auth.get("teams", {}).get(current_org, [])

    table = Table(title=f"Teams in {current_org}", box=box.ROUNDED)
    table.add_column("Name", style="cyan")
    table.add_column("ID", style="dim")
    table.add_column("Members", style="white")
    table.add_column("Role", style="green")

    if not teams_data:
        console.print("[dim]No teams found. Create one with 'hanzo auth teams create'[/dim]")
        return

    for team in teams_data:
        table.add_row(
            team.get("name", ""),
            team.get("id", "")[:12] + "...",
            str(team.get("member_count", 1)),
            team.get("role", "Member"),
        )

    console.print(table)


@teams.command(name="create")
@click.option("--name", "-n", prompt=True, help="Team name")
def teams_create(name: str):
    """Create a new team."""
    import secrets

    auth_mgr = AuthManager()
    if not auth_mgr.is_authenticated():
        console.print("[yellow]Not authenticated[/yellow]")
        return

    team_id = f"team_{secrets.token_hex(8)}"

    auth = auth_mgr.load_auth()
    current_org = auth.get("current_org", "personal")

    if "teams" not in auth:
        auth["teams"] = {}
    if current_org not in auth["teams"]:
        auth["teams"][current_org] = []

    auth["teams"][current_org].append({
        "id": team_id,
        "name": name,
        "role": "Owner",
        "member_count": 1,
        "created": datetime.now().isoformat(),
    })

    auth_mgr.save_auth(auth)

    console.print(f"[green]✓[/green] Team '{name}' created")
    console.print(f"[dim]ID: {team_id}[/dim]")


@teams.command(name="delete")
@click.argument("team_id")
def teams_delete(team_id: str):
    """Delete a team."""
    from rich.prompt import Confirm

    if not Confirm.ask(f"[red]Delete team {team_id}?[/red]"):
        return

    auth_mgr = AuthManager()
    auth = auth_mgr.load_auth()
    current_org = auth.get("current_org", "personal")

    teams_data = auth.get("teams", {}).get(current_org, [])
    original_len = len(teams_data)

    auth["teams"][current_org] = [t for t in teams_data if t.get("id") != team_id and t.get("name") != team_id]

    if len(auth["teams"][current_org]) == original_len:
        console.print(f"[yellow]Team '{team_id}' not found[/yellow]")
        return

    auth_mgr.save_auth(auth)
    console.print(f"[green]✓[/green] Team deleted")
