"""admin 新手引导视频配置:读 / 改开关次数金币 / 上传视频 / 删视频(带审计)。

整份配置存通用 app_config 表(见 app/repositories/guide_video.py),App 领券等候浮层
每次展示前调 POST /api/v1/guide-video/start 同步。权限:operator 可改(运营维护),
super 恒可;读为只读(任意已登录 admin)。

⚠️ 视频上限 100MB(settings.GUIDE_VIDEO_MAX_BYTES),已在 admin nginx 为本接口单独放宽
client_max_body_size,见 shaguabijia-admin-web/deploy/nginx/admin.shaguabijia.com.conf。
"""
from __future__ import annotations

from typing import Annotated, Literal

from fastapi import APIRouter, Depends, File, HTTPException, Request, UploadFile

from app.admin.audit import write_audit
from app.admin.deps import AdminDb, get_client_ip, get_current_admin, require_role
from app.admin.schemas.guide_video import GuideVideoConfigOut, GuideVideoConfigUpdate
from app.core import media
from app.models.admin import AdminUser
from app.repositories import guide_video

router = APIRouter(
    prefix="/admin/api/guide-video",
    tags=["admin-guide-video"],
    dependencies=[Depends(get_current_admin)],
)


GuideScene = Literal["coupon", "comparison"]


def _out(db: AdminDb, scene: GuideScene) -> GuideVideoConfigOut:
    """配置 + 播放统计合成响应(四个写接口都以最新状态返回,前端一次同步到位)。"""
    return GuideVideoConfigOut(
        scene=scene,
        **guide_video.get_config(db, scene),
        **guide_video.play_stats(db, scene),
    )


@router.get("", response_model=GuideVideoConfigOut, summary="新手引导视频配置(领券浮层)")
def get_config(db: AdminDb, scene: GuideScene = "coupon") -> GuideVideoConfigOut:
    return _out(db, scene)


@router.patch("", response_model=GuideVideoConfigOut, summary="改开关/次数/金币(带审计)")
def update_config(
    body: GuideVideoConfigUpdate,
    request: Request,
    admin: Annotated[AdminUser, Depends(require_role("operator"))],
    db: AdminDb,
    scene: GuideScene = "coupon",
) -> GuideVideoConfigOut:
    before, after = guide_video.update_config(
        db,
        enabled=body.enabled,
        max_plays=body.max_plays,
        reward_coin=body.reward_coin,
        scene=scene,
        admin_id=admin.id,
        commit=False,
    )
    write_audit(
        db, admin, action="guide_video.update", target_type="guide_video", target_id=None,
        detail={"scene": scene, "before": before, "after": after}, ip=get_client_ip(request), commit=False,
    )
    db.commit()
    return _out(db, scene)


@router.post("/video", response_model=GuideVideoConfigOut, summary="上传新手引导视频(MP4,带审计)")
async def upload_video(
    request: Request,
    admin: Annotated[AdminUser, Depends(require_role("operator"))],
    db: AdminDb,
    file: Annotated[UploadFile, File()],
    scene: GuideScene = "coupon",
) -> GuideVideoConfigOut:
    data = await file.read()
    try:
        url = media.save_guide_video(data)
    except media.MediaError as e:
        raise HTTPException(status_code=400, detail=str(e)) from e
    before, after = guide_video.set_video(
        db, url, scene=scene, admin_id=admin.id, commit=False
    )
    write_audit(
        db, admin, action="guide_video.set_video", target_type="guide_video", target_id=None,
        detail={"scene": scene, "before": before.get("video_url"), "after": url, "bytes": len(data)},
        ip=get_client_ip(request), commit=False,
    )
    db.commit()
    # 提交成功后再删旧片,避免新片没落库就把旧片丢了
    media.delete_guide_video(before.get("video_url"))
    return _out(db, scene)


@router.delete("/video", response_model=GuideVideoConfigOut, summary="移除新手引导视频(带审计)")
def delete_video(
    request: Request,
    admin: Annotated[AdminUser, Depends(require_role("operator"))],
    db: AdminDb,
    scene: GuideScene = "coupon",
) -> GuideVideoConfigOut:
    """移除后 /guide-video/start 一律返回 should_play=false,领券浮层回到「只放广告」。"""
    before, after = guide_video.set_video(
        db, None, scene=scene, admin_id=admin.id, commit=False
    )
    write_audit(
        db, admin, action="guide_video.delete_video", target_type="guide_video", target_id=None,
        detail={"scene": scene, "before": before.get("video_url")}, ip=get_client_ip(request), commit=False,
    )
    db.commit()
    media.delete_guide_video(before.get("video_url"))
    return _out(db, scene)
