"""Dashboard API endpoints."""
import uuid

from fastapi import APIRouter, Depends, Query
from sqlalchemy import select, func, Integer
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.deps import get_current_user
from app.database import get_db
from app.models.user import User
from app.models.brand import Brand
from app.models.competitor import Competitor
from app.models.query import Query as QueryModel
from app.models.citation_record import CitationRecord
from app.schemas.dashboard import (
    DashboardStatsResponse,
    DimensionScoreItem,
    PlatformScoreItem,
    RecentQueryItem,
)
from app.services.scoring.scoring_service import get_health_level
from app.services.scoring.brand_scoring_data_service import (
    get_brand_scoring_data_service,
    REQUIRED_PLATFORMS,
)
from app.services.cache import get_cache_service, TTL_DASHBOARD

router = APIRouter()


@router.get("/stats", response_model=DashboardStatsResponse)
async def get_dashboard_stats(
    brand_id: uuid.UUID | None = Query(None),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """
    获取看板统计数据

    包括：
    - 综合评分(V2)和较昨日变化
    - 健康等级
    - 五维度评分详情
    - 各平台评分列表（含竞品对比）
    - 竞品地位（领先/落后数量）
    - 最近查询记录
    """
    cache = get_cache_service()
    if brand_id is None:
        brand_stmt = select(Brand).where(Brand.user_id == current_user.id).limit(1)
        brand_result = await db.execute(brand_stmt)
        brand = brand_result.scalar_one_or_none()

        if brand:
            brand_id = brand.id
        else:
            return DashboardStatsResponse(
                overall_score=0.0,
                health_level="danger",
                score_change=0.0,
                platform_scores=[],
                recent_queries=[],
                dimensions=[],
                competitors_ahead=0,
                competitors_behind=0,
                monitored_platforms=0,
                total_platforms=7,
            )

    cache_key = f"dashboard:stats:{current_user.id}:{brand_id}"
    cached = await cache.get_json(cache_key)
    if cached is not None:
        return cached

    brand_stmt = select(Brand).where(Brand.id == brand_id)
    brand_result = await db.execute(brand_stmt)
    brand = brand_result.scalar_one_or_none()
    brand_name = brand.name if brand else None

    scoring_data_service = get_brand_scoring_data_service()

    scoring_data = await scoring_data_service.get_brand_scoring_data(
        db, current_user.id, brand
    )

    overall_score = scoring_data.v2_result.overall_score
    score_change = scoring_data.change_from_yesterday

    dimensions = [
        DimensionScoreItem(
            name=scoring_data.v2_result.mention_rate.name,
            score=round(scoring_data.v2_result.mention_rate.score, 2),
            max_score=scoring_data.v2_result.mention_rate.max_score,
            percentage=round(scoring_data.v2_result.mention_rate.percentage, 2),
        ),
        DimensionScoreItem(
            name=scoring_data.v2_result.recommendation_rank.name,
            score=round(scoring_data.v2_result.recommendation_rank.score, 2),
            max_score=scoring_data.v2_result.recommendation_rank.max_score,
            percentage=round(scoring_data.v2_result.recommendation_rank.percentage, 2),
        ),
        DimensionScoreItem(
            name=scoring_data.v2_result.sentiment_score.name,
            score=round(scoring_data.v2_result.sentiment_score.score, 2),
            max_score=scoring_data.v2_result.sentiment_score.max_score,
            percentage=round(scoring_data.v2_result.sentiment_score.percentage, 2),
        ),
        DimensionScoreItem(
            name=scoring_data.v2_result.citation_quality.name,
            score=round(scoring_data.v2_result.citation_quality.score, 2),
            max_score=scoring_data.v2_result.citation_quality.max_score,
            percentage=round(scoring_data.v2_result.citation_quality.percentage, 2),
        ),
        DimensionScoreItem(
            name=scoring_data.v2_result.competitive_position.name,
            score=round(scoring_data.v2_result.competitive_position.score, 2),
            max_score=scoring_data.v2_result.competitive_position.max_score,
            percentage=round(scoring_data.v2_result.competitive_position.percentage, 2),
        ),
    ]

    ahead_count = scoring_data.competitor_data.get("ahead_count", 0)
    behind_count = scoring_data.competitor_data.get("behind_count", 0)

    platform_scores_dict = scoring_data.platform_scores

    competitor_scores_dict = await scoring_data_service.get_competitor_platform_scores(
        db, current_user.id, brand_id
    )

    competitor_stmt = select(Competitor).where(
        Competitor.brand_id == brand_id
    ).limit(1)
    competitor_result = await db.execute(competitor_stmt)
    first_competitor = competitor_result.scalar_one_or_none()
    competitor_name = first_competitor.name if first_competitor else None

    platform_scores = [
        PlatformScoreItem(
            platform=platform,
            score=score,
            competitor_score=competitor_scores_dict.get(platform),
            competitor_name=competitor_name if competitor_scores_dict.get(platform, 0) > 0 else None,
        )
        for platform, score in platform_scores_dict.items()
    ]

    monitored = sum(1 for s in platform_scores_dict.values() if s > 0)

    recent_queries_stmt = (
        select(QueryModel)
        .where(QueryModel.user_id == current_user.id)
        .order_by(QueryModel.created_at.desc())
        .limit(10)
    )
    recent_queries_result = await db.execute(recent_queries_stmt)
    recent_queries_list = list(recent_queries_result.scalars().all())

    recent_queries = []
    for query in recent_queries_list:
        citation_count_stmt = select(
            func.count().label("total"),
            func.sum(
                func.cast(
                    func.case((CitationRecord.cited == True, 1), else_=0),
                    Integer
                )
            ).label("cited")
        ).where(CitationRecord.query_id == query.id)
        count_result = await db.execute(citation_count_stmt)
        count_row = count_result.one()

        recent_queries.append(RecentQueryItem(
            id=str(query.id),
            keyword=query.keyword,
            target_brand=query.target_brand,
            citation_count=count_row.cited or 0,
            queried_at=query.last_queried_at or query.created_at,
        ))

    health_level = get_health_level(overall_score)

    response = DashboardStatsResponse(
        overall_score=round(overall_score, 2),
        health_level=health_level,
        score_change=score_change,
        platform_scores=platform_scores,
        recent_queries=recent_queries,
        dimensions=dimensions,
        competitors_ahead=ahead_count,
        competitors_behind=behind_count,
        monitored_platforms=monitored,
        total_platforms=7,
        brand_name=brand_name,
    )

    await cache.set_json(
        cache_key,
        response.model_dump(mode="json"),
        expire=TTL_DASHBOARD,
    )

    return response
