"""Account management commands"""
import click
import json
import time
from tabulate import tabulate


@click.group()
def account():
    """Account management commands"""
    pass


@account.command('list')
@click.option('--status', help='Filter by status (active/cooldown/disabled)')
@click.pass_context
def list_accounts(ctx, status):
    """List all accounts"""
    r = ctx.obj['redis']
    
    # 先扫描所有 Space，按账号统计（避免嵌套扫描）
    space_stats = {}  # {username: {'total': N, 'running': M}}
    for skey in r.scan_iter('hfs:space:*', count=500):
        sdata = r.get(skey)
        if sdata:
            s = json.loads(sdata)
            space_id = s.get('id', '')
            if '/' in space_id:
                username = space_id.split('/')[0]
                if username not in space_stats:
                    space_stats[username] = {'total': 0, 'running': 0}
                space_stats[username]['total'] += 1
                if s.get('status') == 'running':
                    space_stats[username]['running'] += 1
    
    accounts = []
    for key in r.scan_iter('hfs:account:*', count=100):
        if ':stats' in key:
            continue
        
        data = r.get(key)
        if data:
            acc = json.loads(data)
            username = acc.get('username', '')
            acc_status = acc.get('status', 'active')
            
            if status and acc_status != status:
                continue
            
            # Check cooldown
            cooldown_until = acc.get('cooldown_until', 0)
            if acc_status == 'cooldown' and cooldown_until <= time.time():
                acc_status = 'active'  # cooldown 已过期
            
            # 从预统计数据获取 Space 数量
            stats = space_stats.get(username, {'total': 0, 'running': 0})
            space_count = stats['total']
            running_count = stats['running']
            
            max_spaces = acc.get('max_spaces', 6)
            usage = f"{running_count}/{space_count}/{max_spaces}"
            
            # 可用性判断
            if acc_status == 'banned':
                available = "banned"
            elif acc_status == 'cooldown':
                cooldown_until = acc.get('cooldown_until', 0)
                if cooldown_until > time.time():
                    available = "cooldown"
                elif space_count >= max_spaces:
                    available = "full"
                else:
                    available = "✓"
            elif space_count >= max_spaces:
                available = "full"
            else:
                available = "✓"
            
            accounts.append([
                acc.get('username', ''),
                acc_status,
                usage,
                available,
            ])
    
    if accounts:
        click.echo(tabulate(accounts, headers=['Username', 'Status', 'Running/Total/Max', 'Avail']))
    else:
        click.echo("No accounts found")


@account.command('show')
@click.argument('username')
@click.pass_context
def show_account(ctx, username):
    """Show account details"""
    r = ctx.obj['redis']
    
    key = f'hfs:account:{username}'
    data = r.get(key)
    
    if not data:
        click.echo(f"Account not found: {username}", err=True)
        ctx.exit(1)
    
    acc = json.loads(data)
    
    click.echo(f"\n📋 Account: {username}\n")
    click.echo(f"Status: {acc.get('status', 'active')}")
    click.echo(f"Token: {acc.get('token', '')[:20]}...")
    click.echo(f"Max Spaces: {acc.get('max_spaces', 6)}")
    click.echo(f"Max Spaces per Project: {acc.get('max_spaces_per_project', 4)}")
    click.echo(f"Created: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(acc.get('created_at', 0)))}")
    
    # Show stats if available
    stats_key = f"{key}:stats"
    stats_data = r.get(stats_key)
    if stats_data:
        stats = json.loads(stats_data)
        
        # Cooldown info
        cooldown = stats.get('cooldown', {})
        if cooldown.get('until', 0) > time.time():
            remaining = int(cooldown['until'] - time.time())
            click.echo(f"\n⏸️  Cooldown: {remaining}s remaining")
            click.echo(f"   Reason: {cooldown.get('reason', 'unknown')}")
            click.echo(f"   Count: {cooldown.get('count', 0)}")
        
        # Today's stats
        today = stats.get('today', {})
        if today:
            click.echo(f"\n📊 Today ({today.get('date', '-')})")
            click.echo(f"   Created: {today.get('spaces_created', 0)}")
            click.echo(f"   Failed: {today.get('spaces_failed', 0)}")
        
        # Total stats
        total = stats.get('total', {})
        if total:
            click.echo(f"\n📈 Total")
            click.echo(f"   Created: {total.get('spaces_created', 0)}")
            click.echo(f"   Failed: {total.get('spaces_failed', 0)}")
    
    # Count current spaces
    space_count = 0
    for space_key in r.scan_iter('hfs:space:*'):
        space_data = r.get(space_key)
        if space_data:
            space = json.loads(space_data)
            if space.get('account') == username and space.get('status') in ('running', 'starting'):
                space_count += 1
    
    click.echo(f"\n🚀 Current Running Spaces: {space_count}")


@account.command('add')
@click.argument('token')
@click.option('--email', help='Email address')
@click.option('--max-spaces', default=6, help='Max total spaces')
@click.option('--max-per-project', default=4, help='Max spaces per project')
@click.pass_context
def add_account(ctx, token, email, max_spaces, max_per_project):
    """Add account (auto-fetch username from token)"""
    r = ctx.obj['redis']
    
    # Fetch username from HF API (REST)
    try:
        import requests
        headers = {"Authorization": f"Bearer {token}"}
        resp = requests.get("https://huggingface.co/api/whoami", headers=headers, timeout=30)
        if resp.status_code != 200:
            raise Exception(f"API returned {resp.status_code}")
        user_info = resp.json()
        username = user_info['name']
        click.echo(f"✓ Fetched username: {username}")
    except Exception as e:
        click.echo(f"Error: Failed to fetch username from token: {e}", err=True)
        ctx.exit(1)
    
    # Check if account already exists
    key = f'hfs:account:{username}'
    if r.exists(key):
        click.echo(f"Account already exists: {username}", err=True)
        click.echo("Use 'hfs-admin account show' to view or update manually", err=True)
        ctx.exit(1)
    
    # Create account
    account_data = {
        'username': username,
        'token': token,
        'status': 'active',
        'max_spaces': max_spaces,
        'max_spaces_per_project': max_per_project,
        'created_at': int(time.time())
    }
    
    if email:
        account_data['email'] = email
    
    r.set(key, json.dumps(account_data))
    
    click.echo(f"✅ Added account: {username}")
    click.echo(f"   Max spaces: {max_spaces}")
    click.echo(f"   Max per project: {max_per_project}")


@account.command('disable')
@click.argument('username')
@click.pass_context
def disable_account(ctx, username):
    """Disable account"""
    r = ctx.obj['redis']
    
    key = f'hfs:account:{username}'
    data = r.get(key)
    
    if not data:
        click.echo(f"Account not found: {username}", err=True)
        ctx.exit(1)
    
    acc = json.loads(data)
    acc['status'] = 'disabled'
    r.set(key, json.dumps(acc))
    
    click.echo(f"✅ Disabled account: {username}")


@account.command('enable')
@click.argument('username')
@click.pass_context
def enable_account(ctx, username):
    """Enable account"""
    r = ctx.obj['redis']
    
    key = f'hfs:account:{username}'
    data = r.get(key)
    
    if not data:
        click.echo(f"Account not found: {username}", err=True)
        ctx.exit(1)
    
    acc = json.loads(data)
    acc['status'] = 'active'
    r.set(key, json.dumps(acc))
    
    # Clear cooldown if any
    stats_key = f"{key}:stats"
    stats_data = r.get(stats_key)
    if stats_data:
        stats = json.loads(stats_data)
        if 'cooldown' in stats:
            stats['cooldown'] = {}
            r.set(stats_key, json.dumps(stats))
            click.echo("✓ Cleared cooldown")
    
    click.echo(f"✅ Enabled account: {username}")


@account.command('reset-score')
@click.argument('username')
@click.option('--score', default=100, help='New score value')
@click.pass_context
def reset_score(ctx, username, score):
    """Reset account score"""
    r = ctx.obj['redis']
    
    key = f'hfs:account:{username}'
    data = r.get(key)
    
    if not data:
        click.echo(f"Account not found: {username}", err=True)
        ctx.exit(1)
    
    acc = json.loads(data)
    old_score = acc.get('score', 100)
    acc['score'] = score
    r.set(key, json.dumps(acc))
    
    click.echo(f"✅ Reset score: {username}")
    click.echo(f"   {old_score} → {score}")
