import uuid
from datetime import datetime, timedelta

from sqlalchemy import func, select, case
from sqlalchemy.ext.asyncio import AsyncSession

from app.models.citation_record import CitationRecord
from app.models.query import Query
from app.models.subscription import Subscription
from app.models.user import User
from app.services.subscription import PLANS


async def get_system_stats(db: AsyncSession) -> dict:
    total_users_result = await db.execute(select(func.count()).select_from(User))
    total_users = total_users_result.scalar_one()

    total_queries_result = await db.execute(select(func.count()).select_from(Query))
    total_queries = total_queries_result.scalar_one()

    total_citations_result = await db.execute(
        select(func.count()).select_from(CitationRecord)
    )
    total_citations = total_citations_result.scalar_one()

    cited_result = await db.execute(
        select(func.count()).select_from(CitationRecord).where(CitationRecord.cited.is_(True))
    )
    cited_count = cited_result.scalar_one()

    citation_rate = round(cited_count / total_citations * 100, 2) if total_citations > 0 else 0.0

    today = datetime.utcnow().date()
    today_start = datetime(today.year, today.month, today.day)
    today_active_result = await db.execute(
        select(func.count(func.distinct(Query.user_id))).where(Query.last_queried_at >= today_start)
    )
    today_active_users = today_active_result.scalar_one()

    return {
        "total_users": total_users,
        "total_queries": total_queries,
        "total_citations": total_citations,
        "citation_rate": citation_rate,
        "today_active_users": today_active_users,
    }


async def get_users(
    db: AsyncSession, skip: int = 0, limit: int = 20, search: str | None = None
) -> dict:
    base_stmt = select(User)
    count_stmt = select(func.count()).select_from(User)

    if search:
        like_pattern = f"%{search}%"
        base_stmt = base_stmt.where(
            (User.email.ilike(like_pattern)) | (User.name.ilike(like_pattern))
        )
        count_stmt = count_stmt.where(
            (User.email.ilike(like_pattern)) | (User.name.ilike(like_pattern))
        )

    base_stmt = base_stmt.order_by(User.created_at.desc()).offset(skip).limit(limit)

    result = await db.execute(base_stmt)
    users = list(result.scalars().all())

    count_result = await db.execute(count_stmt)
    total = count_result.scalar_one()

    if not users:
        return {"items": [], "total": total}

    # 修复 N+1：一次性批量获取所有用户的 query 计数
    user_ids = [u.id for u in users]
    query_count_stmt = (
        select(Query.user_id, func.count().label("cnt"))
        .where(Query.user_id.in_(user_ids))
        .group_by(Query.user_id)
    )
    qc_result = await db.execute(query_count_stmt)
    query_counts: dict = {row.user_id: row.cnt for row in qc_result.all()}

    items = []
    for user in users:
        items.append(
            {
                "id": user.id,
                "email": user.email,
                "name": user.name,
                "plan": user.plan,
                "is_active": user.is_active,
                "is_admin": user.is_admin,
                "email_verified": user.email_verified,
                "query_count": query_counts.get(user.id, 0),
                "created_at": user.created_at,
            }
        )

    return {"items": items, "total": total}


async def get_user_detail(db: AsyncSession, user_id: uuid.UUID) -> dict | None:
    user_result = await db.execute(select(User).where(User.id == user_id))
    user = user_result.scalar_one_or_none()
    if user is None:
        return None

    queries_result = await db.execute(
        select(Query).where(Query.user_id == user_id).order_by(Query.created_at.desc())
    )
    queries = queries_result.scalars().all()

    citations_result = await db.execute(
        select(CitationRecord)
        .join(Query, CitationRecord.query_id == Query.id)
        .where(Query.user_id == user_id)
        .order_by(CitationRecord.queried_at.desc())
        .limit(10)
    )
    citations = citations_result.scalars().all()

    return {
        "user": {
            "id": user.id,
            "email": user.email,
            "name": user.name,
            "plan": user.plan,
            "is_active": user.is_active,
            "is_admin": user.is_admin,
            "email_verified": user.email_verified,
            "max_queries": user.max_queries,
            "created_at": user.created_at,
            "updated_at": user.updated_at,
        },
        "queries": [
            {
                "id": q.id,
                "keyword": q.keyword,
                "target_brand": q.target_brand,
                "status": q.status,
                "frequency": q.frequency,
                "created_at": q.created_at,
            }
            for q in queries
        ],
        "recent_citations": [
            {
                "id": c.id,
                "platform": c.platform,
                "cited": c.cited,
                "citation_position": c.citation_position,
                "queried_at": c.queried_at,
            }
            for c in citations
        ],
    }


async def toggle_user_active(db: AsyncSession, user_id: uuid.UUID) -> dict | None:
    user_result = await db.execute(select(User).where(User.id == user_id))
    user = user_result.scalar_one_or_none()
    if user is None:
        return None

    user.is_active = not user.is_active
    await db.commit()

    return {
        "id": user.id,
        "is_active": user.is_active,
        "message": "用户已启用" if user.is_active else "用户已禁用",
    }


async def update_user_plan(db: AsyncSession, user_id: uuid.UUID, plan: str) -> dict | None:
    plan_data = PLANS.get(plan)
    if plan_data is None:
        raise ValueError(f"Invalid plan: {plan}")

    user_result = await db.execute(select(User).where(User.id == user_id))
    user = user_result.scalar_one_or_none()
    if user is None:
        return None

    user.plan = plan
    user.max_queries = plan_data["max_queries"]
    await db.commit()

    return {
        "id": user.id,
        "plan": user.plan,
        "max_queries": user.max_queries,
        "message": f"用户套餐已更新为{plan_data['name']}",
    }
