"""
应用更新 API
============

为 Tauri updater 插件提供更新检查接口。
"""

from datetime import UTC, datetime

from fastapi import APIRouter, Depends, HTTPException, Query, Response, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.db.session import get_db
from app.models.update import AppRelease, ReleasePackage
from app.schemas.update import (
    ReleaseCreate,
    ReleaseListItem,
    ReleaseResponse,
    TauriPlatformInfo,
    TauriUpdateResponse,
)

router = APIRouter()


@router.get("/check", response_model=TauriUpdateResponse)
async def check_update(
    version: str = Query(..., description="当前应用版本"),
    target: str = Query(..., description="平台：darwin / windows / linux"),
    arch: str = Query(..., description="架构：x86_64 / aarch64"),
    db: AsyncSession = Depends(get_db),
):
    """
    检查应用更新 — Tauri updater 插件入口

    Tauri 启动时会向此接口发送请求，携带当前版本、平台、架构信息。
    如果无需更新，返回 204；如果有更新，返回 Tauri 标准格式的 JSON。
    """
    # 查询最新版本
    result = await db.execute(
        select(AppRelease).order_by(AppRelease.release_date.desc()).limit(1)
    )
    latest: AppRelease | None = result.scalar_one_or_none()

    if not latest:
        return Response(status_code=status.HTTP_204_NO_CONTENT)

    # 已是最新版本（或更高）
    if latest.version == version:
        return Response(status_code=status.HTTP_204_NO_CONTENT)

    # 查询对应平台的包（优先返回 updater 用的包：有 signature 的 .app.tar.gz / .exe）
    result = await db.execute(
        select(ReleasePackage).where(
            ReleasePackage.release_id == latest.id,
            ReleasePackage.platform == target,
            ReleasePackage.architecture == arch,
        ).order_by(
            # 有 signature 的排前面（updater 包），空 signature 的排后面（dmg 安装包）
            ReleasePackage.signature.desc()
        )
    )
    pkgs = result.scalars().all()
    # 取第一个：优先有 signature 的 updater 包；如果没有则取任意一个
    pkg: ReleasePackage | None = pkgs[0] if pkgs else None

    if not pkg:
        # 该平台无包，返回 204（避免报错阻断用户）
        return Response(status_code=status.HTTP_204_NO_CONTENT)

    # 构建 Tauri 格式的响应
    platform_key = f"{target}-{arch}"

    return TauriUpdateResponse(
        version=latest.version,
        notes=latest.notes,
        pub_date=latest.release_date.isoformat() if latest.release_date else None,
        mandatory=latest.mandatory,
        platforms={
            platform_key: TauriPlatformInfo(
                url=pkg.file_url,
                signature=pkg.signature,
            )
        },
    )


@router.post("/releases", response_model=ReleaseResponse, status_code=status.HTTP_201_CREATED)
async def create_release(
    release: ReleaseCreate,
    db: AsyncSession = Depends(get_db),
):
    """
    创建新版本发布（管理员接口）

    用于手动发版时，将构建产物信息写入数据库。
    """
    # 检查版本是否已存在
    result = await db.execute(select(AppRelease).where(AppRelease.version == release.version))
    if result.scalar_one_or_none():
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"版本 {release.version} 已存在",
        )

    # 创建发布记录
    new_release = AppRelease(
        version=release.version,
        release_date=datetime.now(UTC),
        notes=release.notes,
        mandatory=release.mandatory,
    )
    db.add(new_release)
    await db.flush()

    # 创建包记录
    for pkg in release.packages:
        db.add(
            ReleasePackage(
                release_id=new_release.id,
                platform=pkg.platform,
                architecture=pkg.architecture,
                filename=pkg.filename,
                file_url=pkg.file_url,
                file_size=pkg.file_size,
                signature=pkg.signature,
            )
        )

    await db.commit()
    await db.refresh(new_release)

    return ReleaseResponse(
        id=new_release.id,
        version=new_release.version,
        release_date=new_release.release_date,
        notes=new_release.notes,
        mandatory=new_release.mandatory,
        created_at=new_release.created_at,
        packages=[
            {
                "platform": p.platform,
                "architecture": p.architecture,
                "filename": p.filename,
                "file_url": p.file_url,
                "file_size": p.file_size,
                "signature": p.signature,
            }
            for p in new_release.packages
        ],
    )


@router.get("/releases", response_model=list[ReleaseListItem])
async def list_releases(
    db: AsyncSession = Depends(get_db),
):
    """获取所有版本发布列表（管理员接口）"""
    result = await db.execute(select(AppRelease).order_by(AppRelease.release_date.desc()))
    releases = result.scalars().all()

    return [
        ReleaseListItem(
            id=r.id,
            version=r.version,
            release_date=r.release_date,
            notes=r.notes,
            mandatory=r.mandatory,
            package_count=len(r.packages),
        )
        for r in releases
    ]


@router.delete("/releases/{version}")
async def delete_release(
    version: str,
    db: AsyncSession = Depends(get_db),
):
    """删除版本发布（管理员接口）"""
    result = await db.execute(select(AppRelease).where(AppRelease.version == version))
    release = result.scalar_one_or_none()

    if not release:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"版本 {version} 不存在",
        )

    await db.delete(release)
    await db.commit()

    return {"status": "success", "message": f"版本 {version} 已删除"}
