"""
Admin API endpoints for pounce administration.

Provides admin-only access to:
- User management
- TLD price scraping
- System statistics
- Newsletter management
- Domain/Portfolio overview
"""
from datetime import datetime, timedelta
from pathlib import Path
from typing import Optional
from fastapi import APIRouter, HTTPException, status, Depends, BackgroundTasks
from pydantic import BaseModel, EmailStr
from sqlalchemy import select, func, desc

from app.api.deps import Database, get_current_user
from app.config import get_settings
from app.models.user import User
from app.models.subscription import Subscription, SubscriptionTier, SubscriptionStatus, TIER_CONFIG
from app.models.domain import Domain
from app.models.portfolio import PortfolioDomain
from app.models.newsletter import NewsletterSubscriber
from app.models.tld_price import TLDPrice, TLDInfo
from app.models.auction import DomainAuction
from app.models.price_alert import PriceAlert
from app.models.listing import DomainListing
from app.services.db_backup import create_backup, list_backups
from app.services.ops_alerts import run_ops_alert_checks
from app.models.ops_alert import OpsAlertEvent

router = APIRouter()
settings = get_settings()
# ============== Admin Authentication ==============

async def require_admin(
    current_user: User = Depends(get_current_user),
) -> User:
    """Dependency that requires admin privileges."""
    if not current_user.is_admin:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Admin privileges required"
        )
    return current_user


# ============== Scraping Ops (Server-only, free alternative to paid proxies) ==============

class PlaywrightCookiesUpload(BaseModel):
    """Upload Playwright cookies JSON used by protected scrapers (e.g. NameJet)."""
    cookies: list[dict]


@router.post("/scraping/playwright-cookies")
async def upload_playwright_cookies(
    payload: PlaywrightCookiesUpload,
    admin: User = Depends(require_admin),
):
    """Replace the server's Playwright cookie jar file."""
    cookie_dir = Path(__file__).parent.parent / "data" / "cookies"
    cookie_dir.mkdir(parents=True, exist_ok=True)
    cookie_file = cookie_dir / "session_cookies.json"

    if not payload.cookies:
        raise HTTPException(status_code=400, detail="cookies must not be empty")

    try:
        import json
        cookie_file.write_text(json.dumps(payload.cookies, indent=2))
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Failed to write cookie file: {e}")

    return {
        "status": "ok",
        "cookies_count": len(payload.cookies),
        "updated_at": datetime.utcnow().isoformat(),
        "note": "Enable protected scraping with POUNCE_ENABLE_PROTECTED_SCRAPERS=true",
    }


@router.get("/scraping/playwright-cookies")
async def get_playwright_cookie_status(
    admin: User = Depends(require_admin),
):
    """Return Playwright cookie jar status (no contents)."""
    cookie_dir = Path(__file__).parent.parent / "data" / "cookies"
    cookie_file = cookie_dir / "session_cookies.json"

    if not cookie_file.exists():
        return {"exists": False}

    stat = cookie_file.stat()
    return {
        "exists": True,
        "path": str(cookie_file),
        "size_bytes": stat.st_size,
        "modified_at": datetime.utcfromtimestamp(stat.st_mtime).isoformat() + "Z",
    }


# ============== Dashboard Stats ==============

@router.get("/stats")
async def get_admin_stats(
    db: Database,
    admin: User = Depends(require_admin)
):
    """Get comprehensive admin dashboard statistics."""
    
    # User stats
    total_users = await db.execute(select(func.count(User.id)))
    total_users = total_users.scalar()
    
    active_users = await db.execute(
        select(func.count(User.id)).where(User.is_active == True)
    )
    active_users = active_users.scalar()
    
    verified_users = await db.execute(
        select(func.count(User.id)).where(User.is_verified == True)
    )
    verified_users = verified_users.scalar()
    
    # New users last 7 days
    week_ago = datetime.utcnow() - timedelta(days=7)
    new_users_week = await db.execute(
        select(func.count(User.id)).where(User.created_at >= week_ago)
    )
    new_users_week = new_users_week.scalar()
    
    # Subscription stats
    subscriptions_by_tier = {}
    for tier in SubscriptionTier:
        count = await db.execute(
            select(func.count(Subscription.id)).where(
                Subscription.tier == tier,
                Subscription.status == SubscriptionStatus.ACTIVE
            )
        )
        subscriptions_by_tier[tier.value] = count.scalar()
    
    # Domain stats
    total_domains = await db.execute(select(func.count(Domain.id)))
    total_domains = total_domains.scalar()
    
    total_portfolio = await db.execute(select(func.count(PortfolioDomain.id)))
    total_portfolio = total_portfolio.scalar()
    
    # TLD stats
    total_tlds = await db.execute(select(func.count(func.distinct(TLDPrice.tld))))
    total_tlds = total_tlds.scalar()
    
    total_price_records = await db.execute(select(func.count(TLDPrice.id)))
    total_price_records = total_price_records.scalar()
    
    # Newsletter stats
    newsletter_subscribers = await db.execute(
        select(func.count(NewsletterSubscriber.id)).where(NewsletterSubscriber.is_active == True)
    )
    newsletter_subscribers = newsletter_subscribers.scalar()
    
    # Auction stats
    total_auctions = await db.execute(select(func.count(DomainAuction.id)))
    total_auctions = total_auctions.scalar()
    
    # Price alerts
    total_alerts = await db.execute(
        select(func.count(PriceAlert.id)).where(PriceAlert.is_active == True)
    )
    total_alerts = total_alerts.scalar()
    
    return {
        "users": {
            "total": total_users,
            "active": active_users,
            "verified": verified_users,
            "new_this_week": new_users_week,
        },
        "subscriptions": subscriptions_by_tier,
        "domains": {
            "watched": total_domains,
            "portfolio": total_portfolio,
        },
        "tld_data": {
            "unique_tlds": total_tlds,
            "price_records": total_price_records,
        },
        "newsletter_subscribers": newsletter_subscribers,
        "auctions": total_auctions,
        "price_alerts": total_alerts,
    }


# ============== Earnings / Revenue ==============

@router.get("/earnings")
async def get_admin_earnings(
    db: Database,
    admin: User = Depends(require_admin)
):
    """
    Get earnings and revenue metrics for admin dashboard.
    
    Calculates MRR, ARR, and subscription breakdown.
    """
    # Tier prices (from TIER_CONFIG)
    tier_prices = {
        SubscriptionTier.SCOUT: 0,
        SubscriptionTier.TRADER: 9,
        SubscriptionTier.TYCOON: 29,
    }
    
    # Get all active subscriptions
    result = await db.execute(
        select(Subscription).where(
            Subscription.status == SubscriptionStatus.ACTIVE
        )
    )
    active_subs = result.scalars().all()
    
    # Calculate MRR
    mrr = 0.0
    tier_breakdown = {
        "scout": {"count": 0, "revenue": 0},
        "trader": {"count": 0, "revenue": 0},
        "tycoon": {"count": 0, "revenue": 0},
    }
    
    for sub in active_subs:
        price = tier_prices.get(sub.tier, 0)
        mrr += price
        tier_key = sub.tier.value
        if tier_key in tier_breakdown:
            tier_breakdown[tier_key]["count"] += 1
            tier_breakdown[tier_key]["revenue"] += price
    
    arr = mrr * 12
    
    # New subscriptions this week
    week_ago = datetime.utcnow() - timedelta(days=7)
    new_subs_week = await db.execute(
        select(func.count(Subscription.id)).where(
            Subscription.started_at >= week_ago,
            Subscription.tier != SubscriptionTier.SCOUT
        )
    )
    new_subs_week = new_subs_week.scalar() or 0
    
    # New subscriptions this month
    month_ago = datetime.utcnow() - timedelta(days=30)
    new_subs_month = await db.execute(
        select(func.count(Subscription.id)).where(
            Subscription.started_at >= month_ago,
            Subscription.tier != SubscriptionTier.SCOUT
        )
    )
    new_subs_month = new_subs_month.scalar() or 0
    
    # Cancelled subscriptions this month (churn)
    cancelled_month = await db.execute(
        select(func.count(Subscription.id)).where(
            Subscription.cancelled_at >= month_ago,
            Subscription.cancelled_at.isnot(None)
        )
    )
    cancelled_month = cancelled_month.scalar() or 0
    
    # Total paying customers
    paying_customers = tier_breakdown["trader"]["count"] + tier_breakdown["tycoon"]["count"]
    
    # Revenue from Yield (platform's 30% cut)
    try:
        from app.models.yield_domain import YieldTransaction
        yield_revenue = await db.execute(
            select(func.sum(YieldTransaction.net_amount)).where(
                YieldTransaction.created_at >= month_ago,
                YieldTransaction.status == "confirmed"
            )
        )
        yield_revenue_month = float(yield_revenue.scalar() or 0) * 0.30 / 0.70  # Platform's cut
    except Exception:
        yield_revenue_month = 0
    
    return {
        "mrr": round(mrr, 2),
        "arr": round(arr, 2),
        "paying_customers": paying_customers,
        "tier_breakdown": tier_breakdown,
        "new_subscriptions": {
            "week": new_subs_week,
            "month": new_subs_month,
        },
        "churn": {
            "month": cancelled_month,
        },
        "yield_revenue_month": round(yield_revenue_month, 2),
        "total_revenue_month": round(mrr + yield_revenue_month, 2),
        "timestamp": datetime.utcnow().isoformat(),
    }


# ============== Earnings History ==============

@router.get("/earnings/history")
async def get_admin_earnings_history(
    db: Database,
    admin: User = Depends(require_admin),
    months: int = 12
):
    """
    Get historical earnings data for charts.
    
    Calculates MRR for each month based on subscription start dates.
    """
    tier_prices = {
        SubscriptionTier.SCOUT: 0,
        SubscriptionTier.TRADER: 9,
        SubscriptionTier.TYCOON: 29,
    }
    
    # Get all subscriptions
    result = await db.execute(select(Subscription))
    all_subs = result.scalars().all()
    
    # Generate monthly data for the last N months
    monthly_data = []
    now = datetime.utcnow()
    
    for i in range(months - 1, -1, -1):
        # Calculate the start of each month
        month_start = datetime(now.year, now.month, 1) - timedelta(days=i * 30)
        month_end = month_start + timedelta(days=30)
        month_name = month_start.strftime("%b %Y")
        
        # Calculate MRR for this month
        mrr = 0.0
        tier_counts = {"scout": 0, "trader": 0, "tycoon": 0}
        new_subs = 0
        churned = 0
        
        for sub in all_subs:
            # Was this subscription active during this month?
            started_before_month_end = sub.started_at <= month_end
            cancelled_after_month_start = (sub.cancelled_at is None or sub.cancelled_at >= month_start)
            
            if started_before_month_end and cancelled_after_month_start:
                price = tier_prices.get(sub.tier, 0)
                mrr += price
                tier_key = sub.tier.value
                if tier_key in tier_counts:
                    tier_counts[tier_key] += 1
            
            # New subscriptions in this month
            if month_start <= sub.started_at < month_end and sub.tier != SubscriptionTier.SCOUT:
                new_subs += 1
            
            # Churned in this month
            if sub.cancelled_at and month_start <= sub.cancelled_at < month_end:
                churned += 1
        
        monthly_data.append({
            "month": month_name,
            "mrr": round(mrr, 2),
            "arr": round(mrr * 12, 2),
            "paying_customers": tier_counts["trader"] + tier_counts["tycoon"],
            "scout": tier_counts["scout"],
            "trader": tier_counts["trader"],
            "tycoon": tier_counts["tycoon"],
            "new_subscriptions": new_subs,
            "churn": churned,
        })
    
    # Calculate growth metrics
    if len(monthly_data) >= 2:
        current_mrr = monthly_data[-1]["mrr"]
        prev_mrr = monthly_data[-2]["mrr"] if monthly_data[-2]["mrr"] > 0 else 1
        mrr_growth = ((current_mrr - prev_mrr) / prev_mrr) * 100
    else:
        mrr_growth = 0
    
    # Calculate average revenue per user (ARPU)
    current_paying = monthly_data[-1]["paying_customers"] if monthly_data else 0
    current_mrr = monthly_data[-1]["mrr"] if monthly_data else 0
    arpu = current_mrr / current_paying if current_paying > 0 else 0
    
    # Calculate LTV (assuming 12 month average retention)
    ltv = arpu * 12
    
    return {
        "monthly_data": monthly_data,
        "metrics": {
            "mrr_growth_percent": round(mrr_growth, 1),
            "arpu": round(arpu, 2),
            "ltv": round(ltv, 2),
            "total_customers": sum(m["paying_customers"] for m in monthly_data[-1:]),
        },
        "timestamp": datetime.utcnow().isoformat(),
    }


# ============== User Management ==============

class UpdateUserRequest(BaseModel):
    """Schema for updating user."""
    name: Optional[str] = None
    is_active: Optional[bool] = None
    is_verified: Optional[bool] = None
    is_admin: Optional[bool] = None


class UpgradeUserRequest(BaseModel):
    """Request schema for upgrading a user."""
    email: EmailStr
    tier: str  # scout, trader, tycoon


@router.get("/users")
async def list_users(
    db: Database,
    admin: User = Depends(require_admin),
    limit: int = 50,
    offset: int = 0,
    search: Optional[str] = None,
):
    """List all users with pagination and search."""
    # PERF: Avoid N+1 queries (subscription + domain_count per user).
    domain_counts = (
        select(
            Domain.user_id.label("user_id"),
            func.count(Domain.id).label("domain_count"),
        )
        .group_by(Domain.user_id)
        .subquery()
    )

    base = (
        select(
            User,
            Subscription,
            func.coalesce(domain_counts.c.domain_count, 0).label("domain_count"),
        )
        .outerjoin(Subscription, Subscription.user_id == User.id)
        .outerjoin(domain_counts, domain_counts.c.user_id == User.id)
    )
    
    if search:
        base = base.where(
            User.email.ilike(f"%{search}%") | User.name.ilike(f"%{search}%")
        )
    
    # Total count (for pagination UI)
    count_query = select(func.count(User.id))
    if search:
        count_query = count_query.where(
            User.email.ilike(f"%{search}%") | User.name.ilike(f"%{search}%")
        )
    total = (await db.execute(count_query)).scalar() or 0

    result = await db.execute(
        base.order_by(desc(User.created_at)).offset(offset).limit(limit)
        )
    rows = result.all()

    user_list = []
    for user, subscription, domain_count in rows:
        user_list.append(
            {
            "id": user.id,
            "email": user.email,
            "name": user.name,
            "is_active": user.is_active,
            "is_verified": user.is_verified,
            "is_admin": user.is_admin,
            "created_at": user.created_at.isoformat(),
            "last_login": user.last_login.isoformat() if user.last_login else None,
                "domain_count": int(domain_count or 0),
            "subscription": {
                "tier": subscription.tier.value if subscription else "scout",
                "tier_name": TIER_CONFIG.get(subscription.tier, {}).get("name", "Scout") if subscription else "Scout",
                "status": subscription.status.value if subscription else None,
                "domain_limit": subscription.domain_limit if subscription else 5,
            } if subscription else {
                "tier": "scout",
                "tier_name": "Scout",
                "status": None,
                "domain_limit": 5,
            },
            }
        )
    
    return {"users": user_list, "total": total, "limit": limit, "offset": offset}


# ============== User Export ==============
# NOTE: This must come BEFORE /users/{user_id} to avoid route conflict

@router.get("/users/export")
async def export_users_csv(
    db: Database,
    admin: User = Depends(require_admin),
):
    """Export all users as CSV data."""
    import csv
    import io
    
    domain_counts = (
        select(
            Domain.user_id.label("user_id"),
            func.count(Domain.id).label("domain_count"),
        )
        .group_by(Domain.user_id)
        .subquery()
    )

    result = await db.execute(
        select(
            User,
            Subscription,
            func.coalesce(domain_counts.c.domain_count, 0).label("domain_count"),
        )
        .outerjoin(Subscription, Subscription.user_id == User.id)
        .outerjoin(domain_counts, domain_counts.c.user_id == User.id)
        .order_by(User.created_at)
    )
    users_list = result.all()
    
    # Create CSV
    output = io.StringIO()
    writer = csv.writer(output)
    
    # Header
    writer.writerow([
        "ID", "Email", "Name", "Active", "Verified", "Admin",
        "Created At", "Last Login", "Tier", "Domain Limit", "Domains Used"
    ])
    
    for user, subscription, domain_count in users_list:
        writer.writerow([
            user.id,
            user.email,
            user.name or "",
            "Yes" if user.is_active else "No",
            "Yes" if user.is_verified else "No",
            "Yes" if user.is_admin else "No",
            user.created_at.strftime("%Y-%m-%d %H:%M"),
            user.last_login.strftime("%Y-%m-%d %H:%M") if user.last_login else "",
            subscription.tier.value if subscription else "scout",
            subscription.domain_limit if subscription else 5,
            int(domain_count or 0),
        ])
    
    return {
        "csv": output.getvalue(),
        "count": len(users_list),
        "exported_at": datetime.utcnow().isoformat(),
    }


@router.get("/users/{user_id}")
async def get_user(
    user_id: int,
    db: Database,
    admin: User = Depends(require_admin),
):
    """Get detailed user information."""
    result = await db.execute(select(User).where(User.id == user_id))
    user = result.scalar_one_or_none()
    
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    
    # Get subscription
    sub_result = await db.execute(
        select(Subscription).where(Subscription.user_id == user.id)
    )
    subscription = sub_result.scalar_one_or_none()
    
    # Get domains
    domains_result = await db.execute(
        select(Domain).where(Domain.user_id == user.id)
    )
    domains = domains_result.scalars().all()
    
    # Get portfolio
    portfolio_result = await db.execute(
        select(PortfolioDomain).where(PortfolioDomain.user_id == user.id)
    )
    portfolio = portfolio_result.scalars().all()
    
    return {
        "id": user.id,
        "email": user.email,
        "name": user.name,
        "is_active": user.is_active,
        "is_verified": user.is_verified,
        "is_admin": user.is_admin,
        "stripe_customer_id": user.stripe_customer_id,
        "created_at": user.created_at.isoformat(),
        "updated_at": user.updated_at.isoformat(),
        "last_login": user.last_login.isoformat() if user.last_login else None,
        "subscription": {
            "tier": subscription.tier.value if subscription else None,
            "status": subscription.status.value if subscription else None,
            "domain_limit": subscription.domain_limit if subscription else 0,
            "stripe_subscription_id": subscription.stripe_subscription_id if subscription else None,
        } if subscription else None,
        "domains": [
            {
                "id": d.id,
                "domain": d.domain,
                "status": d.status,
                "created_at": d.created_at.isoformat(),
            }
            for d in domains
        ],
        "portfolio": [
            {
                "id": p.id,
                "domain": p.domain,
                "purchase_price": p.purchase_price,
                "estimated_value": p.estimated_value,
            }
            for p in portfolio
        ],
    }


@router.patch("/users/{user_id}")
async def update_user(
    user_id: int,
    request: UpdateUserRequest,
    db: Database,
    admin: User = Depends(require_admin),
):
    """Update user details."""
    result = await db.execute(select(User).where(User.id == user_id))
    user = result.scalar_one_or_none()
    
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    
    if request.name is not None:
        user.name = request.name
    if request.is_active is not None:
        user.is_active = request.is_active
    if request.is_verified is not None:
        user.is_verified = request.is_verified
    if request.is_admin is not None:
        user.is_admin = request.is_admin
    
    await db.commit()
    await db.refresh(user)
    
    return {"message": f"User {user.email} updated", "user_id": user.id}


@router.delete("/users/{user_id}")
async def delete_user(
    user_id: int,
    db: Database,
    admin: User = Depends(require_admin),
):
    """Delete a user and all their data."""
    from app.models.blog import BlogPost
    from app.models.admin_log import AdminActivityLog
    
    result = await db.execute(select(User).where(User.id == user_id))
    user = result.scalar_one_or_none()
    
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    
    if user.is_admin:
        raise HTTPException(status_code=400, detail="Cannot delete admin user")
    
    user_email = user.email
    
    # Delete user's blog posts (or set author_id to NULL if you want to keep them)
    await db.execute(
        BlogPost.__table__.delete().where(BlogPost.author_id == user_id)
    )
    
    # Delete user's admin activity logs (if any)
    await db.execute(
        AdminActivityLog.__table__.delete().where(AdminActivityLog.admin_id == user_id)
    )
    
    # Now delete the user (cascades to domains, subscriptions, portfolio, price_alerts)
    await db.delete(user)
    await db.commit()
    
    # Log this action
    await log_admin_activity(
        db, admin.id, "user_delete",
        f"Deleted user {user_email} and all their data"
    )
    
    return {"message": f"User {user_email} and all their data have been deleted"}


@router.post("/users/{user_id}/upgrade")
async def upgrade_user(
    user_id: int,
    tier: str,
    db: Database,
    admin: User = Depends(require_admin),
):
    """Upgrade a user's subscription tier."""
    result = await db.execute(select(User).where(User.id == user_id))
    user = result.scalar_one_or_none()
    
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    
    # Validate tier
    try:
        new_tier = SubscriptionTier(tier)
    except ValueError:
        raise HTTPException(
            status_code=400,
            detail=f"Invalid tier: {tier}. Valid: scout, trader, tycoon"
        )
    
    # Find or create subscription
    sub_result = await db.execute(
        select(Subscription).where(Subscription.user_id == user.id)
    )
    subscription = sub_result.scalar_one_or_none()
    
    config = TIER_CONFIG.get(new_tier, {})
    
    if not subscription:
        subscription = Subscription(
            user_id=user.id,
            tier=new_tier,
            status=SubscriptionStatus.ACTIVE,
            max_domains=config.get("domain_limit", 5),
        )
        db.add(subscription)
    else:
        subscription.tier = new_tier
        subscription.max_domains = config.get("domain_limit", 5)
        subscription.status = SubscriptionStatus.ACTIVE
    
    await db.commit()
    
    return {
        "message": f"User {user.email} upgraded to {config.get('name', tier)}",
        "tier": new_tier.value,
    }


# ============== Newsletter Management ==============

@router.get("/newsletter")
async def list_newsletter_subscribers(
    db: Database,
    admin: User = Depends(require_admin),
    limit: int = 100,
    offset: int = 0,
    active_only: bool = True,
):
    """List newsletter subscribers."""
    query = select(NewsletterSubscriber).order_by(desc(NewsletterSubscriber.subscribed_at))
    
    if active_only:
        query = query.where(NewsletterSubscriber.is_active == True)
    
    query = query.offset(offset).limit(limit)
    result = await db.execute(query)
    subscribers = result.scalars().all()
    
    # Total count
    count_query = select(func.count(NewsletterSubscriber.id))
    if active_only:
        count_query = count_query.where(NewsletterSubscriber.is_active == True)
    total = await db.execute(count_query)
    total = total.scalar()
    
    return {
        "subscribers": [
            {
                "id": s.id,
                "email": s.email,
                "is_active": s.is_active,
                "subscribed_at": s.subscribed_at.isoformat(),
                "unsubscribed_at": s.unsubscribed_at.isoformat() if s.unsubscribed_at else None,
            }
            for s in subscribers
        ],
        "total": total,
    }


@router.get("/newsletter/export")
async def export_newsletter_emails(
    db: Database,
    admin: User = Depends(require_admin),
):
    """Export all active newsletter emails (for external tools)."""
    result = await db.execute(
        select(NewsletterSubscriber.email).where(NewsletterSubscriber.is_active == True)
    )
    emails = [row[0] for row in result.fetchall()]
    
    return {
        "emails": emails,
        "count": len(emails),
    }


# ============== TLD Management ==============

@router.post("/scrape-tld-prices")
async def trigger_tld_scrape(
    db: Database,
    admin: User = Depends(require_admin),
):
    """Manually trigger a TLD price scrape."""
    # Prefer job queue in production (non-blocking)
    if settings.enable_job_queue and settings.redis_url:
        from app.jobs.client import enqueue_job

        job_id = await enqueue_job("scrape_tld_prices")
        return {"message": "TLD price scrape enqueued", "job_id": job_id}

    # Fallback: run inline
    from app.services.tld_scraper.aggregator import tld_aggregator
    
    result = await tld_aggregator.run_scrape(db)
    
    return {
        "message": "TLD price scrape completed",
        "status": result.status,
        "tlds_scraped": result.tlds_scraped,
        "prices_saved": result.prices_saved,
        "sources_succeeded": result.sources_succeeded,
        "sources_attempted": result.sources_attempted,
        "errors": result.errors,
        "started_at": result.started_at.isoformat(),
        "completed_at": result.completed_at.isoformat() if result.completed_at else None,
    }


@router.get("/tld-prices/stats")
async def get_tld_price_stats(
    db: Database,
    admin: User = Depends(require_admin),
):
    """Get TLD price data statistics."""
    # Total records
    total = await db.execute(select(func.count(TLDPrice.id)))
    total_records = total.scalar()
    
    # Unique TLDs
    tlds = await db.execute(select(func.count(func.distinct(TLDPrice.tld))))
    unique_tlds = tlds.scalar()
    
    # Unique registrars
    registrars = await db.execute(select(func.count(func.distinct(TLDPrice.registrar))))
    unique_registrars = registrars.scalar()
    
    # Latest record
    latest = await db.execute(
        select(TLDPrice.recorded_at).order_by(desc(TLDPrice.recorded_at)).limit(1)
    )
    latest_record = latest.scalar()
    
    # Oldest record
    oldest = await db.execute(
        select(TLDPrice.recorded_at).order_by(TLDPrice.recorded_at.asc()).limit(1)
    )
    oldest_record = oldest.scalar()
    
    return {
        "total_records": total_records,
        "unique_tlds": unique_tlds,
        "unique_registrars": unique_registrars,
        "latest_record": latest_record.isoformat() if latest_record else None,
        "oldest_record": oldest_record.isoformat() if oldest_record else None,
        "data_range_days": (latest_record - oldest_record).days if latest_record and oldest_record else 0,
    }


# ============== System ==============

@router.get("/system/health")
async def system_health(
    db: Database,
    admin: User = Depends(require_admin),
):
    """Check system health."""
    # Test database
    try:
        await db.execute(select(1))
        db_status = "healthy"
    except Exception as e:
        db_status = f"error: {str(e)}"
    
    # Check email config
    from app.services.email_service import EmailService
    email_configured = EmailService.is_configured()
    
    # Check Stripe config
    import os
    stripe_configured = bool(os.getenv("STRIPE_SECRET_KEY"))
    
    return {
        "status": "healthy" if db_status == "healthy" else "degraded",
        "database": db_status,
        "email_configured": email_configured,
        "stripe_configured": stripe_configured,
        "timestamp": datetime.utcnow().isoformat(),
    }


@router.post("/system/make-admin")
async def make_user_admin(
    email: str,
    db: Database,
):
    """
    Make a user an admin. 
    NOTE: This endpoint has NO authentication for initial setup!
    In production, disable after first admin is created.
    """
    result = await db.execute(select(User).where(User.email == email))
    user = result.scalar_one_or_none()
    
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    
    user.is_admin = True
    await db.commit()
    
    return {"message": f"User {email} is now an admin"}


# ============== Price Alerts ==============

@router.get("/price-alerts")
async def list_price_alerts(
    db: Database,
    admin: User = Depends(require_admin),
    limit: int = 100,
    offset: int = 0,
):
    """List all active price alerts with user info."""
    query = (
        select(PriceAlert, User)
        .join(User, PriceAlert.user_id == User.id)
        .where(PriceAlert.is_active == True)
        .order_by(desc(PriceAlert.created_at))
        .offset(offset)
        .limit(limit)
    )
    result = await db.execute(query)
    alerts = result.all()
    
    # Total count
    count_query = select(func.count(PriceAlert.id)).where(PriceAlert.is_active == True)
    total = await db.execute(count_query)
    total = total.scalar()
    
    return {
        "alerts": [
            {
                "id": alert.id,
                "tld": alert.tld,
                "target_price": float(alert.target_price) if alert.target_price else None,
                "alert_type": alert.alert_type,
                "created_at": alert.created_at.isoformat(),
                "user": {
                    "id": user.id,
                    "email": user.email,
                    "name": user.name,
                }
            }
            for alert, user in alerts
        ],
        "total": total,
    }


# ============== Domain Health ==============

@router.post("/domains/check-all")
async def trigger_domain_checks(
    background_tasks: BackgroundTasks,
    db: Database,
    admin: User = Depends(require_admin),
):
    """Manually trigger domain availability checks for all watched domains."""
    from app.services.domain_checker import check_all_domains
    
    # Count domains to check
    total_domains = await db.execute(select(func.count(Domain.id)))
    total_domains = total_domains.scalar()
    
    if total_domains == 0:
        return {"message": "No domains to check", "domains_queued": 0}
    
    # Run in background
    background_tasks.add_task(check_all_domains, db)
    
    return {
        "message": "Domain checks started",
        "domains_queued": total_domains,
        "started_at": datetime.utcnow().isoformat(),
    }


# ============== Email Test ==============

@router.post("/system/test-email")
async def test_email(
    db: Database,
    admin: User = Depends(require_admin),
):
    """Send a test email to the admin user."""
    from app.services.email_service import email_service
    
    if not email_service.is_configured():
        raise HTTPException(
            status_code=400,
            detail="Email service is not configured. Check SMTP settings."
        )
    
    try:
        await email_service.send_email(
            to_email=admin.email,
            subject="pounce Admin Panel - Test Email",
            html_content=f"""
            <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
                <h1 style="color: #22c55e;">✅ Email Test Successful</h1>
                <p>This is a test email from the pounce Admin Panel.</p>
                <p>If you received this, your SMTP configuration is working correctly.</p>
                <hr style="border: none; border-top: 1px solid #e5e5e5; margin: 20px 0;">
                <p style="color: #666; font-size: 12px;">
                    Sent at: {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S UTC')}<br>
                    Admin: {admin.email}
                </p>
            </div>
            """,
            text_content=f"Email Test Successful\n\nThis is a test email from the pounce Admin Panel.\nSent at: {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S UTC')}"
        )
        return {
            "message": "Test email sent successfully",
            "sent_to": admin.email,
            "timestamp": datetime.utcnow().isoformat(),
        }
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"Failed to send email: {str(e)}"
        )


# ============== Scheduler Status ==============

@router.get("/system/scheduler")
async def get_scheduler_status(
    db: Database,
    admin: User = Depends(require_admin),
):
    """Get scheduler job status and last run times."""
    from app.scheduler import scheduler
    
    jobs = []
    for job in scheduler.get_jobs():
        jobs.append({
            "id": job.id,
            "name": job.name,
            "next_run": job.next_run_time.isoformat() if job.next_run_time else None,
            "trigger": str(job.trigger),
        })
    
    # Get last scrape times from database
    # TLD scrape - check latest TLD price record
    latest_tld = await db.execute(
        select(TLDPrice.recorded_at).order_by(desc(TLDPrice.recorded_at)).limit(1)
    )
    latest_tld = latest_tld.scalar()
    
    # Auction scrape - check latest auction record
    latest_auction = await db.execute(
        select(DomainAuction.scraped_at).order_by(desc(DomainAuction.scraped_at)).limit(1)
    )
    latest_auction = latest_auction.scalar()
    
    # Domain check - check latest domain check (via Domain.last_checked)
    latest_domain_check = await db.execute(
        select(Domain.last_checked).where(Domain.last_checked.isnot(None)).order_by(desc(Domain.last_checked)).limit(1)
    )
    latest_domain_check = latest_domain_check.scalar()
    
    return {
        "scheduler_running": scheduler.running,
        "jobs": jobs,
        "last_runs": {
            "tld_scrape": latest_tld.isoformat() if latest_tld else None,
            "auction_scrape": latest_auction.isoformat() if latest_auction else None,
            "domain_check": latest_domain_check.isoformat() if latest_domain_check else None,
        },
        "timestamp": datetime.utcnow().isoformat(),
    }


# ============== Ops: Backups (4B) ==============

@router.get("/system/backups")
async def get_backups(
    admin: User = Depends(require_admin),
    limit: int = 20,
):
    """List recent DB backups on the server."""
    return {"backups": list_backups(limit=limit)}


@router.post("/system/backups")
async def create_db_backup(
    admin: User = Depends(require_admin),
    verify: bool = True,
):
    """Create a DB backup on the server (and verify it)."""
    if not settings.enable_db_backups:
        raise HTTPException(status_code=403, detail="DB backups are disabled (ENABLE_DB_BACKUPS=false).")
    try:
        result = create_backup(verify=verify)
        return {
            "status": "ok",
            "backup": {
                "path": result.path,
                "size_bytes": result.size_bytes,
                "created_at": result.created_at,
                "verified": result.verified,
                "verification_detail": result.verification_detail,
            },
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Backup failed: {e}")


@router.post("/system/ops-alerts/run")
async def run_ops_alerts_now(
    admin: User = Depends(require_admin),
):
    """
    Run ops alert checks immediately (and send alerts if enabled).
    Useful for server validation without Docker.
    """
    return await run_ops_alert_checks()


@router.get("/system/ops-alerts/history")
async def get_ops_alert_history(
    db: Database,
    admin: User = Depends(require_admin),
    limit: int = 100,
):
    """Return recent persisted ops alert events."""
    limit = max(1, min(int(limit), 500))
    rows = (
        await db.execute(
            select(OpsAlertEvent).order_by(OpsAlertEvent.created_at.desc()).limit(limit)
        )
    ).scalars().all()
    return {
        "events": [
            {
                "id": e.id,
                "alert_key": e.alert_key,
                "severity": e.severity,
                "title": e.title,
                "detail": e.detail,
                "status": e.status,
                "send_reason": e.send_reason,
                "recipients": e.recipients,
                "created_at": e.created_at.isoformat(),
            }
            for e in rows
        ]
    }


# ============== Bulk Operations ==============

class BulkUpgradeRequest(BaseModel):
    """Request for bulk tier upgrade."""
    user_ids: list[int]
    tier: str


@router.post("/users/bulk-upgrade")
async def bulk_upgrade_users(
    request: BulkUpgradeRequest,
    db: Database,
    admin: User = Depends(require_admin),
):
    """Upgrade multiple users to a specific tier."""
    # Validate tier
    try:
        new_tier = SubscriptionTier(request.tier)
    except ValueError:
        raise HTTPException(
            status_code=400,
            detail=f"Invalid tier: {request.tier}. Valid: scout, trader, tycoon"
        )
    
    config = TIER_CONFIG.get(new_tier, {})
    upgraded = []
    failed = []
    
    for user_id in request.user_ids:
        try:
            # Get user
            result = await db.execute(select(User).where(User.id == user_id))
            user = result.scalar_one_or_none()
            
            if not user:
                failed.append({"user_id": user_id, "reason": "User not found"})
                continue
            
            # Get or create subscription
            sub_result = await db.execute(
                select(Subscription).where(Subscription.user_id == user.id)
            )
            subscription = sub_result.scalar_one_or_none()
            
            if not subscription:
                subscription = Subscription(
                    user_id=user.id,
                    tier=new_tier,
                    status=SubscriptionStatus.ACTIVE,
                    max_domains=config.get("domain_limit", 5),
                )
                db.add(subscription)
            else:
                subscription.tier = new_tier
                subscription.max_domains = config.get("domain_limit", 5)
                subscription.status = SubscriptionStatus.ACTIVE
            
            upgraded.append({"user_id": user_id, "email": user.email})
            
        except Exception as e:
            failed.append({"user_id": user_id, "reason": str(e)})
    
    await db.commit()
    
    # Log activity
    await log_admin_activity(
        db, admin.id, "bulk_upgrade",
        f"Upgraded {len(upgraded)} users to {new_tier.value}"
    )
    
    return {
        "message": f"Bulk upgrade completed",
        "tier": new_tier.value,
        "upgraded": upgraded,
        "failed": failed,
        "total_upgraded": len(upgraded),
        "total_failed": len(failed),
    }


# ============== Activity Log ==============

async def log_admin_activity(
    db: Database,
    admin_id: int,
    action: str,
    details: str,
):
    """Helper to log admin activities."""
    from app.models.admin_log import AdminActivityLog
    
    try:
        log = AdminActivityLog(
            admin_id=admin_id,
            action=action,
            details=details,
        )
        db.add(log)
        await db.commit()
    except Exception:
        # Don't fail if logging fails
        pass


@router.get("/activity-log")
async def get_activity_log(
    db: Database,
    admin: User = Depends(require_admin),
    limit: int = 50,
    offset: int = 0,
):
    """Get admin activity log."""
    from app.models.admin_log import AdminActivityLog
    
    query = (
        select(AdminActivityLog, User)
        .join(User, AdminActivityLog.admin_id == User.id)
        .order_by(desc(AdminActivityLog.created_at))
        .offset(offset)
        .limit(limit)
    )
    
    try:
        result = await db.execute(query)
        logs = result.all()
    except Exception:
        # Table might not exist yet
        return {"logs": [], "total": 0}
    
    # Total count
    try:
        count_query = select(func.count(AdminActivityLog.id))
        total = await db.execute(count_query)
        total = total.scalar()
    except Exception:
        total = 0
    
    return {
        "logs": [
            {
                "id": log.id,
                "action": log.action,
                "details": log.details,
                "created_at": log.created_at.isoformat(),
                "admin": {
                    "id": user.id,
                    "email": user.email,
                    "name": user.name,
                }
            }
            for log, user in logs
        ],
        "total": total,
    }


# ============== API Connection Tests ==============

@router.get("/test-apis")
async def test_external_apis(
    admin: User = Depends(require_admin),
):
    """
    Test connections to all external APIs.
    
    Returns status of:
    - DropCatch API
    - Sedo API
    - Moz API (if configured)
    """
    from app.services.dropcatch_api import dropcatch_client
    from app.services.sedo_api import sedo_client
    
    results = {
        "tested_at": datetime.utcnow().isoformat(),
        "apis": {}
    }
    
    # Test DropCatch API
    try:
        dropcatch_result = await dropcatch_client.test_connection()
        results["apis"]["dropcatch"] = dropcatch_result
    except Exception as e:
        results["apis"]["dropcatch"] = {
            "success": False,
            "error": str(e),
            "configured": dropcatch_client.is_configured
        }
    
    # Test Sedo API
    try:
        sedo_result = await sedo_client.test_connection()
        results["apis"]["sedo"] = sedo_result
    except Exception as e:
        results["apis"]["sedo"] = {
            "success": False,
            "error": str(e),
            "configured": sedo_client.is_configured
        }
    
    # Summary
    results["summary"] = {
        "total": len(results["apis"]),
        "configured": sum(1 for api in results["apis"].values() if api.get("configured")),
        "connected": sum(1 for api in results["apis"].values() if api.get("success")),
    }
    
    return results


@router.post("/trigger-scrape")
async def trigger_auction_scrape(
    db: Database,
    admin: User = Depends(require_admin),
):
    """
    Manually trigger auction scraping from all sources.
    
    This will:
    1. Try Tier 1 APIs (DropCatch, Sedo) first
    2. Fall back to web scraping for others
    """
    # Prefer job queue in production (non-blocking)
    if settings.enable_job_queue and settings.redis_url:
        from app.jobs.client import enqueue_job

        job_id = await enqueue_job("scrape_auctions")
        return {
            "message": "Auction scraping enqueued",
            "job_id": job_id,
            "note": "Check /admin/scrape-status for results",
        }

    # Fallback: run inline
    from app.services.auction_scraper import AuctionScraperService
    
    scraper = AuctionScraperService()
    result = await scraper.scrape_all_platforms(db)
    
    return {
        "message": "Auction scraping completed",
        "result": result,
        "note": "Check /admin/scrape-status for results",
    }


@router.get("/scrape-status")
async def get_scrape_status(
    db: Database,
    admin: User = Depends(require_admin),
    limit: int = 10,
):
    """Get recent scrape logs."""
    from app.models.auction import AuctionScrapeLog
    
    query = (
        select(AuctionScrapeLog)
        .order_by(desc(AuctionScrapeLog.started_at))
        .limit(limit)
    )
    
    try:
        result = await db.execute(query)
        logs = result.scalars().all()
    except Exception:
        return {"logs": [], "error": "Table not found"}
    
    return {
        "logs": [
            {
                "id": log.id,
                "platform": log.platform,
                "status": log.status,
                "auctions_found": log.auctions_found,
                "auctions_new": log.auctions_new,
                "auctions_updated": log.auctions_updated,
                "error_message": log.error_message,
                "started_at": log.started_at.isoformat() if log.started_at else None,
                "completed_at": log.completed_at.isoformat() if log.completed_at else None,
            }
            for log in logs
        ]
    }


# ============== Subscription Management ==============

class SubscriptionUpdate(BaseModel):
    """Manual subscription update request."""
    tier: str  # "scout", "trader", "tycoon"


@router.post("/users/{user_id}/sync-subscription")
async def sync_user_subscription_from_stripe(
    user_id: int,
    db: Database,
    admin: User = Depends(require_admin),
):
    """
    Sync a user's subscription status from Stripe.
    
    Use this if the webhook failed to update the subscription.
    """
    import stripe
    import os
    
    stripe.api_key = os.getenv("STRIPE_SECRET_KEY")
    
    if not stripe.api_key:
        raise HTTPException(status_code=503, detail="Stripe not configured")
    
    # Get user
    result = await db.execute(select(User).where(User.id == user_id))
    user = result.scalar_one_or_none()
    
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    
    if not user.stripe_customer_id:
        raise HTTPException(status_code=400, detail="User has no Stripe customer ID")
    
    # Get subscriptions from Stripe
    try:
        subscriptions = stripe.Subscription.list(
            customer=user.stripe_customer_id,
            status="active",
            limit=1
        )
    except stripe.error.StripeError as e:
        raise HTTPException(status_code=500, detail=f"Stripe error: {e}")
    
    if not subscriptions.data:
        return {
            "status": "no_active_subscription",
            "message": "No active subscription found in Stripe",
            "user_email": user.email,
            "stripe_customer_id": user.stripe_customer_id
        }
    
    stripe_sub = subscriptions.data[0]
    # Access items via dict notation (Stripe returns StripeObject)
    items_data = stripe_sub.get("items", {}).get("data", [])
    price_id = items_data[0].get("price", {}).get("id") if items_data else None
    
    # Map price_id to tier
    trader_price = os.getenv("STRIPE_PRICE_TRADER")
    tycoon_price = os.getenv("STRIPE_PRICE_TYCOON")
    
    if price_id == trader_price:
        tier = SubscriptionTier.TRADER
        tier_name = "trader"
    elif price_id == tycoon_price:
        tier = SubscriptionTier.TYCOON
        tier_name = "tycoon"
    else:
        return {
            "status": "unknown_price",
            "message": f"Unknown price ID: {price_id}",
            "stripe_subscription_id": stripe_sub.id
        }
    
    # Update subscription in database
    sub_result = await db.execute(
        select(Subscription).where(Subscription.user_id == user.id)
    )
    subscription = sub_result.scalar_one_or_none()
    
    tier_config = TIER_CONFIG[tier]
    
    if subscription:
        old_tier = subscription.tier
        subscription.tier = tier
        subscription.status = SubscriptionStatus.ACTIVE
        subscription.stripe_subscription_id = stripe_sub.id
        subscription.max_domains = tier_config["domain_limit"]
        subscription.check_frequency = tier_config["check_frequency"]
    else:
        subscription = Subscription(
            user_id=user.id,
            tier=tier,
            status=SubscriptionStatus.ACTIVE,
            stripe_subscription_id=stripe_sub.id,
            max_domains=tier_config["domain_limit"],
            check_frequency=tier_config["check_frequency"],
        )
        db.add(subscription)
        old_tier = None
    
    await db.commit()
    
    return {
        "status": "synced",
        "user_email": user.email,
        "stripe_customer_id": user.stripe_customer_id,
        "stripe_subscription_id": stripe_sub.id,
        "old_tier": old_tier.value if old_tier else None,
        "new_tier": tier.value,
        "tier_config": {
            "domain_limit": tier_config["domain_limit"],
            "check_frequency": tier_config["check_frequency"],
        }
    }


@router.post("/users/{user_id}/set-subscription")
async def set_user_subscription(
    user_id: int,
    update: SubscriptionUpdate,
    db: Database,
    admin: User = Depends(require_admin),
):
    """
    Manually set a user's subscription tier.
    
    Use this to manually upgrade/downgrade users (e.g., for refunds or promotions).
    """
    tier_map = {
        "scout": SubscriptionTier.SCOUT,
        "trader": SubscriptionTier.TRADER,
        "tycoon": SubscriptionTier.TYCOON,
    }
    
    if update.tier.lower() not in tier_map:
        raise HTTPException(status_code=400, detail=f"Invalid tier: {update.tier}")
    
    tier = tier_map[update.tier.lower()]
    
    # Get user
    result = await db.execute(select(User).where(User.id == user_id))
    user = result.scalar_one_or_none()
    
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    
    # Get/create subscription
    sub_result = await db.execute(
        select(Subscription).where(Subscription.user_id == user.id)
    )
    subscription = sub_result.scalar_one_or_none()
    
    tier_config = TIER_CONFIG[tier]
    
    if subscription:
        old_tier = subscription.tier
        subscription.tier = tier
        subscription.status = SubscriptionStatus.ACTIVE
        subscription.max_domains = tier_config["domain_limit"]
        subscription.check_frequency = tier_config["check_frequency"]
    else:
        subscription = Subscription(
            user_id=user.id,
            tier=tier,
            status=SubscriptionStatus.ACTIVE,
            max_domains=tier_config["domain_limit"],
            check_frequency=tier_config["check_frequency"],
        )
        db.add(subscription)
        old_tier = None
    
    await db.commit()
    
    return {
        "status": "updated",
        "user_email": user.email,
        "user_id": user.id,
        "old_tier": old_tier.value if old_tier else None,
        "new_tier": tier.value,
    }


# ============== Listing Debug Endpoints ==============

@router.get("/listings/debug")
async def debug_listings(
    domain: Optional[str] = None,
    slug: Optional[str] = None,
    db: Database = None,
    _: User = Depends(require_admin),
):
    """Debug listings - search by domain or slug (ignores status)."""
    query = select(DomainListing)
    
    if domain:
        query = query.where(DomainListing.domain.ilike(f"%{domain}%"))
    if slug:
        query = query.where(DomainListing.slug.ilike(f"%{slug}%"))
    
    query = query.order_by(desc(DomainListing.created_at)).limit(20)
    
    result = await db.execute(query)
    listings = list(result.scalars().all())
    
    return {
        "count": len(listings),
        "listings": [
            {
                "id": l.id,
                "domain": l.domain,
                "slug": l.slug,
                "status": l.status,
                "is_verified": l.is_verified,
                "verification_status": l.verification_status,
                "public_url": l.public_url,
                "created_at": str(l.created_at) if l.created_at else None,
                "published_at": str(l.published_at) if l.published_at else None,
                "user_id": l.user_id,
            }
            for l in listings
        ]
    }


@router.post("/listings/{listing_id}/force-activate")
async def force_activate_listing(
    listing_id: int,
    db: Database = None,
    _: User = Depends(require_admin),
):
    """Force-activate a listing (bypass DNS verification)."""
    result = await db.execute(
        select(DomainListing).where(DomainListing.id == listing_id)
    )
    listing = result.scalar_one_or_none()
    
    if not listing:
        raise HTTPException(status_code=404, detail="Listing not found")
    
    listing.status = "active"
    listing.is_verified = True
    listing.verification_status = "verified"
    listing.published_at = datetime.utcnow()
    
    await db.commit()
    
    return {
        "status": "activated",
        "listing_id": listing.id,
        "domain": listing.domain,
        "slug": listing.slug,
        "public_url": listing.public_url,
    }


# ============== Zone File Sync ==============

@router.post("/zone-sync/switch")
async def trigger_switch_sync(
    background_tasks: BackgroundTasks,
    db: Database,
    admin: User = Depends(require_admin),
):
    """
    Trigger manual Switch.ch zone file sync (.ch, .li).
    Admin only.
    """
    from app.services.zone_file import ZoneFileService
    
    async def run_sync():
        from app.database import AsyncSessionLocal
        async with AsyncSessionLocal() as session:
            zf = ZoneFileService()
            for tld in ["ch", "li"]:
                await zf.run_daily_sync(session, tld)
            return {"status": "complete"}
    
    background_tasks.add_task(run_sync)
    
    return {
        "status": "started",
        "message": "Switch.ch zone sync started in background. Check logs for progress.",
    }


@router.post("/zone-sync/czds")
async def trigger_czds_sync(
    background_tasks: BackgroundTasks,
    db: Database,
    admin: User = Depends(require_admin),
):
    """
    Trigger manual ICANN CZDS zone file sync (gTLDs).
    Admin only.
    """
    from app.services.czds_client import CZDSClient
    
    async def run_sync():
        from app.database import AsyncSessionLocal
        async with AsyncSessionLocal() as session:
            client = CZDSClient()
            result = await client.sync_all_zones(session, parallel=True)
            return result
    
    background_tasks.add_task(run_sync)
    
    return {
        "status": "started",
        "message": "ICANN CZDS zone sync started in background (parallel mode). Check logs for progress.",
    }


@router.get("/zone-sync/status")
async def get_zone_sync_status(
    db: Database,
    admin: User = Depends(require_admin),
):
    """
    Get zone sync status and statistics.
    Admin only.
    """
    from app.models.zone_file import ZoneSnapshot, DroppedDomain
    from sqlalchemy import func, desc
    from datetime import timedelta
    
    now = datetime.utcnow()
    today = now.replace(hour=0, minute=0, second=0, microsecond=0)
    yesterday = today - timedelta(days=1)
    
    # Get latest snapshots per TLD
    snapshots_stmt = (
        select(
            ZoneSnapshot.tld,
            func.max(ZoneSnapshot.created_at).label("last_sync"),
            func.max(ZoneSnapshot.domain_count).label("domain_count"),
        )
        .group_by(ZoneSnapshot.tld)
    )
    result = await db.execute(snapshots_stmt)
    snapshots = {row.tld: {"last_sync": row.last_sync, "domain_count": row.domain_count} for row in result.all()}
    
    # Get drops count per TLD for today
    drops_today_stmt = (
        select(
            DroppedDomain.tld,
            func.count(DroppedDomain.id).label("count"),
        )
        .where(DroppedDomain.dropped_date >= today)
        .group_by(DroppedDomain.tld)
    )
    result = await db.execute(drops_today_stmt)
    drops_today = {row.tld: row.count for row in result.all()}
    
    # Total drops per TLD
    total_drops_stmt = (
        select(
            DroppedDomain.tld,
            func.count(DroppedDomain.id).label("count"),
        )
        .group_by(DroppedDomain.tld)
    )
    result = await db.execute(total_drops_stmt)
    total_drops = {row.tld: row.count for row in result.all()}
    
    # Build status for each TLD
    all_tlds = set(snapshots.keys()) | set(drops_today.keys()) | set(total_drops.keys())
    
    zones = []
    for tld in sorted(all_tlds):
        snapshot = snapshots.get(tld, {})
        last_sync = snapshot.get("last_sync")
        
        zones.append({
            "tld": tld,
            "last_sync": last_sync.isoformat() if last_sync else None,
            "domain_count": snapshot.get("domain_count", 0),
            "drops_today": drops_today.get(tld, 0),
            "total_drops": total_drops.get(tld, 0),
            "status": "healthy" if last_sync and last_sync > yesterday else "stale" if last_sync else "never",
        })
    
    return {
        "zones": zones,
        "summary": {
            "total_zones": len(zones),
            "healthy": sum(1 for z in zones if z["status"] == "healthy"),
            "stale": sum(1 for z in zones if z["status"] == "stale"),
            "never_synced": sum(1 for z in zones if z["status"] == "never"),
            "total_drops_today": sum(drops_today.values()),
            "total_drops_all": sum(total_drops.values()),
        }
    }
