"""관리자 API — Bearer 토큰 인증. 경기/AI예측 upsert + 결과 입력(채점)."""
from __future__ import annotations

from fastapi import APIRouter, Depends, Header, HTTPException
from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession

from ..config import settings
from ..database import get_db
from ..domain import now_utc
from ..models import AIPrediction, Match, PageVisit
from ..schemas import AdminAIPredictionIn, AdminSetResultIn, DailyVisitOut, GenericOk
from ..services.grading import apply_result

router = APIRouter(prefix="/api/admin", tags=["admin"])


def require_admin(authorization: str = Header(default="")) -> None:
    token = authorization.removeprefix("Bearer ").strip()
    if not token or token != settings.admin_api_token:
        raise HTTPException(status_code=401, detail="UNAUTHORIZED")


@router.post("/ai-predictions", response_model=GenericOk, dependencies=[Depends(require_admin)])
async def upsert_ai_prediction(
    body: AdminAIPredictionIn, db: AsyncSession = Depends(get_db)
) -> GenericOk:
    match = (
        await db.execute(select(Match).where(Match.match_id == body.matchId))
    ).scalars().first()
    if not match:
        raise HTTPException(status_code=404, detail="MATCH_NOT_FOUND")

    pred = (
        await db.execute(
            select(AIPrediction).where(
                AIPrediction.match_id == body.matchId, AIPrediction.model == body.model
            )
        )
    ).scalars().first()
    if pred is None:
        pred = AIPrediction(match_id=body.matchId, model=body.model)
        db.add(pred)
    pred.outcome = body.outcome
    pred.score_a = body.scoreA
    pred.score_b = body.scoreB
    pred.confidence_pct = body.confidencePct
    pred.reason_ko = body.reasonKo
    pred.reason_en = body.reasonEn
    pred.generated_at = now_utc()
    pred.source = "admin"
    await db.commit()
    return GenericOk(ok=True, detail="upserted")


@router.post("/result", response_model=GenericOk, dependencies=[Depends(require_admin)])
async def set_result(
    body: AdminSetResultIn, db: AsyncSession = Depends(get_db)
) -> GenericOk:
    match = (
        await db.execute(select(Match).where(Match.match_id == body.matchId))
    ).scalars().first()
    if not match:
        raise HTTPException(status_code=404, detail="MATCH_NOT_FOUND")

    graded = await apply_result(db, match, body.scoreA, body.scoreB)
    # 결과 메일은 워커가 result_email_delay_minutes 경과 후 발송(@finished_at 기준).
    return GenericOk(
        ok=True,
        detail="result set & graded",
        extra={"gradedPicks": graded, "emailsSentBy": "worker"},
    )


@router.get(
    "/visits", response_model=list[DailyVisitOut], dependencies=[Depends(require_admin)]
)
async def daily_visits(db: AsyncSession = Depends(get_db)) -> list[DailyVisitOut]:
    """일별 순수 방문자 수 (최신순)."""
    rows = (
        await db.execute(
            select(PageVisit.visit_date, func.count())
            .group_by(PageVisit.visit_date)
            .order_by(PageVisit.visit_date.desc())
        )
    ).all()
    return [DailyVisitOut(date=d.isoformat(), uniqueVisitors=c) for d, c in rows]
