"""Dashboard view."""

from __future__ import annotations

from sqlalchemy import func
from sqlalchemy import select
from sqlalchemy.orm import joinedload
from starlette.requests import Request
from starlette.responses import Response

from fenliu.config import settings
from fenliu.database import get_db
from fenliu.models import HashtagStream
from fenliu.models import Post
from fenliu.services.api_key import get_api_key
from fenliu.templates_env import templates
from fenliu.utils.display import process_post_for_display
from fenliu.utils.display import process_stream_for_display


async def dashboard(request: Request) -> Response:
    """Render the dashboard page."""
    with get_db() as db:
        # Get statistics
        total_streams: int = db.scalar(select(func.count()).select_from(HashtagStream))
        active_streams: int = db.scalar(select(func.count()).select_from(HashtagStream).where(HashtagStream.active))
        total_posts: int = db.scalar(select(func.count()).select_from(Post))
        processed_posts: int = db.scalar(select(func.count()).select_from(Post).where(Post.processed))

        # Get curated queue posts (approved and in queue)
        stmt = (
            select(Post)
            .options(joinedload(Post.stream))
            .where(Post.approved.is_(True))
            .where(Post.queue_status.isnot(None))
            .order_by(Post.reserved_at.desc(), Post.export_date.desc())
            .limit(20)
        )
        result = db.execute(stmt)
        recent_posts = list(result.scalars().all())

        # Get active streams
        stmt = select(HashtagStream).where(HashtagStream.active).order_by(HashtagStream.hashtag)
        result = db.execute(stmt)
        active_streams_list = list(result.scalars().all())

        # Process posts to make datetimes timezone-aware and serialize
        processed_posts_list = [process_post_for_display(post) for post in recent_posts]

        # Load post counts per stream in one query then look up by stream id
        stream_post_counts: dict[int, int] = {
            int(row[0]): int(row[1])
            for row in db.execute(select(Post.stream_id, func.count()).group_by(Post.stream_id)).all()
        }

        # Process streams to make datetimes timezone-aware and add post counts
        processed_streams = []
        for stream in active_streams_list:
            stream_dict = process_stream_for_display(stream)
            stream_dict["post_count"] = stream_post_counts.get(stream.id, 0)
            processed_streams.append(stream_dict)

        # Get API key if it exists
        api_key = get_api_key(db)

        context = {
            "total_streams": total_streams,
            "active_streams": active_streams,
            "total_posts": total_posts,
            "processed_posts": processed_posts,
            "curated_posts": processed_posts_list,
            "active_streams_list": processed_streams,
            "app_name": settings.app_name,
            "app_version": settings.app_version,
            "api_key": api_key or "",
        }
        return templates.TemplateResponse(request, "dashboard.html", context)
