"""Command-line interface for CirtusAI SDK."""

import argparse
import getpass
import json
import sys
from typing import Optional

from .client import CirtusClient
from .credentials import clear_credentials, load_credentials, save_credentials
from .exceptions import APIError, AuthenticationError, CirtusSDKError


def get_client() -> CirtusClient:
    """Load credentials and create an authenticated client."""
    creds = load_credentials()
    if not creds:
        print("Error: Not logged in. Run 'cirtus init' first.", file=sys.stderr)
        sys.exit(1)
    
    try:
        return CirtusClient(
            base_url=creds["base_url"],
            api_key=creds["api_key"],
        )
    except Exception as e:
        print(f"Error: Failed to initialize client: {e}", file=sys.stderr)
        sys.exit(1)


def cmd_init(args: argparse.Namespace) -> None:
    """Register agent and save credentials."""
    base_url = args.url or input("Enter base URL (e.g., https://api.cirtusai.com): ").strip()
    agent_name = args.agent_name or input("Enter agent name: ").strip()
    password = args.password or getpass.getpass("Enter password: ")
    
    if not base_url or not agent_name or not password:
        print("Error: All fields are required.", file=sys.stderr)
        sys.exit(1)
    
    try:
        # Check if already registered, if so login instead
        print(f"Attempting to register {agent_name}...")
        try:
            result = CirtusClient.register(base_url, agent_name, password)
            print(f"✓ Successfully registered {agent_name}")
        except APIError as e:
            if e.status_code == 400:
                print(f"Agent already exists, logging in instead...")
            else:
                raise
        
        # Login to get access token
        login_result = CirtusClient.login(base_url, agent_name, password)
        access_token = login_result.get("access_token")
        expires_at = login_result.get("expires_at")
        
        if not access_token:
            print("Error: Login succeeded but no access token received.", file=sys.stderr)
            sys.exit(1)
        
        # Create an API key for permanent access using JWT token
        # We create a temporary client with the JWT token (not as api_key)
        from datetime import datetime, timezone
        client = CirtusClient(base_url=base_url, api_key="dummy", auto_authenticate=False)
        client._token = access_token
        # Set a future expiry so _token_expired() returns False
        if expires_at:
            from cirtusai.client import _parse_datetime
            client._token_expiry = _parse_datetime(expires_at)
        else:
            client._token_expiry = datetime.now(timezone.utc).replace(year=2099)
        client._session.headers.update({"Authorization": f"Bearer {access_token}"})
        
        print("Creating API key...")
        api_key_result = client.create_api_key(f"{agent_name}-cli")
        api_key = api_key_result.get("secret")
        
        if not api_key:
            print("Error: Failed to create API key.", file=sys.stderr)
            sys.exit(1)
        
        # Save credentials
        save_credentials(api_key, base_url, agent_name)
        print(f"✓ Credentials saved to {load_credentials.__doc__}")
        print(f"✓ Agent {agent_name} is ready!")
        
    except AuthenticationError as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)
    except APIError as e:
        print(f"Error: API request failed (status {e.status_code})", file=sys.stderr)
        if e.detail:
            print(f"Details: {json.dumps(e.detail, indent=2)}", file=sys.stderr)
        sys.exit(1)
    except CirtusSDKError as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


def cmd_identity(args: argparse.Namespace) -> None:
    """Show identity document."""
    client = get_client()
    
    try:
        identity = client.get_identity()
        
        print(f"Identity: {identity.name}")
        print(f"  ID: {identity.id}")
        print(f"  Type: {identity.type}")
        print(f"  Status: {identity.status}")
        print(f"  Created: {identity.create_time}")
        
        if identity.reputation:
            print(f"\nReputation:")
            print(f"  Score: {identity.reputation.score}")
            print(f"  Trust Level: {identity.reputation.trust_level}")
            # Stake feature temporarily disabled
            # print(f"  Staked Amount: {identity.reputation.total_staked}")
            # print(f"  Active Stakes: {identity.reputation.active_stakes}")
        
        if identity.rate_limit:
            print(f"\nRate Limits:")
            print(f"  Per Minute: {identity.rate_limit.requests_per_minute}")
            print(f"  Per Day: {identity.rate_limit.requests_per_day}")
            print(f"  Current Usage: {identity.rate_limit.current_usage}")
        
        print(f"\nAssets: {len(identity.assets)}")
        for asset in identity.assets:
            print(f"  - {asset.type}: {asset.address} ({asset.status})")
        
        print(f"\nLinked Platforms: {len(identity.linked_platforms)}")
        for platform in identity.linked_platforms:
            print(f"  - {platform.name}: {platform.connection_status}")
        
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


def cmd_mail_list(args: argparse.Namespace) -> None:
    """List emails."""
    client = get_client()
    
    try:
        messages = client.list_messages(
            folder=args.folder,
            limit=args.limit,
            unread=args.unread if hasattr(args, 'unread') and args.unread is not None else None,
        )
        
        if not messages:
            print("No messages found.")
            return
        
        print(f"Found {len(messages)} message(s):\n")
        for msg in messages:
            status = "●" if msg.unread else "○"
            print(f"{status} [{msg.id}] {msg.sender}")
            print(f"  Subject: {msg.subject}")
            if msg.preview:
                print(f"  Preview: {msg.preview[:60]}...")
            print()
        
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


def cmd_mail_send(args: argparse.Namespace) -> None:
    """Send an email."""
    to = args.to
    subject = args.subject
    body = args.body
    
    if not to or not subject or not body:
        print("Error: --to, --subject, and --body are required.", file=sys.stderr)
        sys.exit(1)

    client = get_client()
    
    try:
        result = client.send_message(
            to=[to],
            subject=subject,
            content=body,
        )
        print(f"✓ Message sent successfully!")
        if result.get("id"):
            print(f"  Message ID: {result['id']}")
        
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


def cmd_stake_list(args: argparse.Namespace) -> None:
    """Show stakes."""
    client = get_client()
    
    try:
        result = client.list_stakes()
        stakes = result.get("items", [])
        
        if not stakes:
            print("No stakes found.")
            return
        
        print(f"Found {len(stakes)} stake(s):\n")
        for stake in stakes:
            print(f"Stake ID: {stake.get('id')}")
            print(f"  Tier: {stake.get('tier')}")
            print(f"  Amount: {stake.get('amount')}")
            print(f"  Status: {stake.get('status')}")
            print(f"  Lock Days: {stake.get('lock_days')}")
            print(f"  Created: {stake.get('created_at')}")
            print()
        
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


def cmd_stake_create(args: argparse.Namespace) -> None:
    """Create a stake."""
    tier = args.tier
    lock_days = args.lock_days or 30
    
    if not tier:
        print("Error: --tier is required.", file=sys.stderr)
        sys.exit(1)

    client = get_client()
    
    try:
        result = client.create_stake(tier=tier, lock_days=lock_days)
        print(f"✓ Stake created successfully!")
        print(f"  Stake ID: {result.get('id')}")
        print(f"  Tier: {result.get('tier')}")
        print(f"  Amount: {result.get('amount')}")
        print(f"  Lock Days: {result.get('lock_days')}")
        
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


def cmd_logout(args: argparse.Namespace) -> None:
    """Clear saved credentials."""
    clear_credentials()
    print("✓ Logged out successfully.")


def main() -> None:
    """Main entry point for the CLI."""
    parser = argparse.ArgumentParser(
        prog="cirtusai",
        description="CirtusAI CLI - Manage agents, identities, and mail",
    )
    
    subparsers = parser.add_subparsers(dest="command", help="Available commands")
    
    # Init command
    init_parser = subparsers.add_parser("init", help="Register agent and save credentials")
    init_parser.add_argument("--url", help="Base URL of the CirtusAI API")
    init_parser.add_argument("--agent-name", help="Agent name")
    init_parser.add_argument("--password", help="Password (will prompt if not provided)")
    
    # Identity command
    subparsers.add_parser("identity", help="Show identity document")
    
    # Mail commands
    mail_parser = subparsers.add_parser("mail", help="Mail operations")
    mail_subparsers = mail_parser.add_subparsers(dest="mail_command", help="Mail commands")
    
    mail_list_parser = mail_subparsers.add_parser("list", help="List emails")
    mail_list_parser.add_argument("--folder", default="inbox", help="Folder to list (default: inbox)")
    mail_list_parser.add_argument("--limit", type=int, default=30, help="Maximum messages to fetch")
    mail_list_parser.add_argument("--unread", action="store_true", help="Show only unread messages")
    
    mail_send_parser = mail_subparsers.add_parser("send", help="Send an email")
    mail_send_parser.add_argument("--to", required=True, help="Recipient email address")
    mail_send_parser.add_argument("--subject", required=True, help="Email subject")
    mail_send_parser.add_argument("--body", required=True, help="Email body")
    
    # Stake commands - temporarily disabled
    # stake_parser = subparsers.add_parser("stake", help="Stake operations")
    # stake_subparsers = stake_parser.add_subparsers(dest="stake_command", help="Stake commands")
    # stake_subparsers.add_parser("list", help="Show stakes")
    # stake_create_parser = stake_subparsers.add_parser("create", help="Create a new stake")
    # stake_create_parser.add_argument("--tier", required=True, help="Stake tier (e.g., bronze, silver, gold)")
    # stake_create_parser.add_argument("--lock-days", type=int, default=30, help="Lock period in days (default: 30)")
    
    # Logout command
    subparsers.add_parser("logout", help="Clear saved credentials")
    
    args = parser.parse_args()
    
    if not args.command:
        parser.print_help()
        sys.exit(1)
    
    # Route to appropriate handler
    if args.command == "init":
        cmd_init(args)
    elif args.command == "identity":
        cmd_identity(args)
    elif args.command == "mail":
        if not hasattr(args, 'mail_command') or not args.mail_command:
            mail_parser.print_help()
            sys.exit(1)
        if args.mail_command == "list":
            cmd_mail_list(args)
        elif args.mail_command == "send":
            cmd_mail_send(args)
    # Stake commands - temporarily disabled
    # elif args.command == "stake":
    #     if not hasattr(args, 'stake_command') or not args.stake_command:
    #         stake_parser.print_help()
    #         sys.exit(1)
    #     if args.stake_command == "list":
    #         cmd_stake_list(args)
    #     elif args.stake_command == "create":
    #         cmd_stake_create(args)
    elif args.command == "logout":
        cmd_logout(args)
    else:
        parser.print_help()
        sys.exit(1)


if __name__ == "__main__":
    main()
