from fastapi import APIRouter, Depends, File, HTTPException, UploadFile, status
from fastapi.responses import FileResponse

from app.core.deps import get_superuser
from app.models.user import User
from app.schemas import BackupInfoOut
from app.services import backup as backup_service

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


@router.get("", response_model=list[BackupInfoOut])
def list_backups(_: User = Depends(get_superuser)):
    return backup_service.list_backups()


@router.post("/run", response_model=BackupInfoOut)
def run_backup(_: User = Depends(get_superuser)):
    try:
        path = backup_service.create_backup()
    except FileNotFoundError as exc:
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(exc)) from exc
    except Exception as exc:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"备份失败: {exc}",
        ) from exc
    stat = path.stat()
    from datetime import datetime, timezone

    return BackupInfoOut(
        filename=path.name,
        size_bytes=stat.st_size,
        created_at=datetime.fromtimestamp(stat.st_mtime, tz=timezone.utc),
    )


@router.get("/{filename}/download")
def download_backup(filename: str, _: User = Depends(get_superuser)):
    try:
        path = backup_service.resolve_backup_file(filename)
    except ValueError as exc:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
    except FileNotFoundError as exc:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="备份不存在") from exc
    return FileResponse(
        path,
        media_type="application/gzip",
        filename=filename,
        headers={"Content-Disposition": f'attachment; filename="{filename}"'},
    )


@router.post("/restore")
async def restore_backup(file: UploadFile = File(...), _: User = Depends(get_superuser)):
    if not file.filename or not file.filename.endswith(".tar.gz"):
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="请上传 .tar.gz 备份包")
    content = await file.read()
    if len(content) > 512 * 1024 * 1024:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="备份文件过大（最大 512MB）")

    import tempfile
    from pathlib import Path

    tmp = Path(tempfile.mkdtemp(prefix="grade-archive-upload-"))
    archive = tmp / "restore.tar.gz"
    try:
        archive.write_bytes(content)
        backup_service.restore_backup(archive)
    except Exception as exc:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"恢复失败: {exc}",
        ) from exc
    finally:
        import shutil

        shutil.rmtree(tmp, ignore_errors=True)

    return {"ok": True, "message": "数据已恢复，建议重启服务以确保缓存刷新"}
