from fastapi import APIRouter, Depends, File, UploadFile
from sqlalchemy.ext.asyncio import AsyncSession
from starlette.responses import FileResponse

from app.database.session import get_db, engine
from app.domain.entities.responses.backup import BackupResponseEntity
from app.infrastructure.backup_service import BackupService
from app.infrastructure.dependencies import require_admin
from app.settings import settings

router = APIRouter()


@router.get(
    '/',
    response_model=list[BackupResponseEntity],
    summary='Get all backups',
    description='Get all backups',
)
async def get_all_backups(
        db: AsyncSession = Depends(get_db),
        user=Depends(require_admin),
):
    backup_service = BackupService(db)
    return await backup_service.get_all_backups()


@router.get(
    '/{backup_id}/file/',
    response_class=FileResponse,
    summary='Get a backup file',
    description='Get a backup file',
)
async def get_backup(
        backup_id: int,
        db: AsyncSession = Depends(get_db),
        user=Depends(require_admin),
):
    backup_service = BackupService(db)
    return await backup_service.get_backup_file_by_id(backup_id)


@router.post(
    "/",
    response_model=BackupResponseEntity,
    summary="Create backup",
    description="Create backup",
)
async def create_backup(
        db: AsyncSession = Depends(get_db),
        user=Depends(require_admin),
):
    backup_service = BackupService(
        db,
        settings.BACKUP_DB_URL,
        settings.FILE_UPLOAD_DIR,
        settings.BACKUP_DIR,
        settings.PG_DUMP_PATH,
    )
    return await backup_service.create_backup(user.id)


@router.post(
    '/upload/',
    response_model=BackupResponseEntity,
    summary='Upload a backup',
    description='Upload a backup',
)
async def upload_backup(
        file: UploadFile = File(...),
        db: AsyncSession = Depends(get_db),
        user=Depends(require_admin),
):
    backup_service = BackupService(
        db,
        backup_dir=settings.BACKUP_DIR,
        app_files_dir=settings.FILE_UPLOAD_DIR,
    )
    return await backup_service.upload_backup(file, user)


@router.delete(
    '/{backup_id}/',
    response_model=BackupResponseEntity,
    summary='Delete backup',
    description='Delete backup',
)
async def delete_backup(
        backup_id: int,
        db: AsyncSession = Depends(get_db),
        user=Depends(require_admin),
):
    backup_service = BackupService(
        db,
        settings.BACKUP_DB_URL,
        settings.FILE_UPLOAD_DIR,
        settings.BACKUP_DIR,
        settings.PG_DUMP_PATH,
    )
    return await backup_service.delete_backup(backup_id)
