from fastapi import APIRouter, Body, Depends, HTTPException, status
from sqlalchemy.orm import Session

from app.api.deps import require_roles
from app.db.session import SessionLocal, get_db
from app.models import AdminUser
from app.schemas.backup import (
    CreateDatabaseBackupRequest,
    DatabaseBackupOut,
    RestoreDatabaseBackupOut,
    RestoreDatabaseBackupRequest,
)
from app.services.db_backup import BackupError, create_database_backup, list_database_backups, restore_database_backup
from app.services.logs import log_action

router = APIRouter()


@router.get("", response_model=list[DatabaseBackupOut])
def list_backups(
    _: AdminUser = Depends(require_roles("system_admin")),
) -> list[dict[str, object]]:
    return list_database_backups()


@router.post("", response_model=DatabaseBackupOut)
def create_backup(
    payload: CreateDatabaseBackupRequest | None = Body(default=None),
    db: Session = Depends(get_db),
    current_admin: AdminUser = Depends(require_roles("system_admin")),
) -> dict[str, object]:
    try:
        backup = create_database_backup(reason=payload.reason if payload else "manual")
    except BackupError as exc:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc

    log_action(
        db,
        current_admin,
        "create_database_backup",
        "database_backup",
        backup["filename"],
        detail={
            "filename": backup["filename"],
            "database_type": backup["database_type"],
            "size_label": backup["size_label"],
            "reason": backup.get("reason"),
        },
    )
    db.commit()
    return backup


@router.post("/{filename}/restore", response_model=RestoreDatabaseBackupOut)
def restore_backup(
    filename: str,
    payload: RestoreDatabaseBackupRequest,
    db: Session = Depends(get_db),
    current_admin: AdminUser = Depends(require_roles("system_admin")),
) -> dict[str, object]:
    db.close()
    try:
        result = restore_database_backup(filename, payload.confirmation)
    except BackupError as exc:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc

    with SessionLocal() as log_db:
        log_action(
            log_db,
            current_admin,
            "restore_database_backup",
            "database_backup",
            filename,
            detail={
                "filename": filename,
                "restored_backup": result["restored_backup"],
                "pre_restore_backup": result["pre_restore_backup"],
            },
        )
        log_db.commit()

    return result
