"""
Discard API router
"""
import os
import logging
from fastapi import APIRouter, Depends, HTTPException, Body
from sqlalchemy import select, and_
from sqlalchemy.ext.asyncio import AsyncSession

from app.database import get_db
from app.models import Photo
from app.models.user import User
from app.dependencies import get_current_user

logger = logging.getLogger(__name__)

router = APIRouter()

@router.get("")
async def list_discarded(db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user)):
    """List discarded photos"""
    result = await db.execute(
        select(Photo).where(Photo.is_discarded == True, Photo.user_id == current_user.id)
    )
    photos = result.scalars().all()
    return photos

@router.post("/restore")
async def restore_photos(photo_ids: list[str], db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user)):
    """Restore photos from the discard pile"""
    result = await db.execute(
        select(Photo).where(and_(Photo.id.in_(photo_ids), Photo.is_discarded == True, Photo.user_id == current_user.id))
    )
    photos = result.scalars().all()

    for photo in photos:
        photo.is_discarded = False
        photo.discarded_at = None

    await db.commit()
    return {"status": "success", "restored": len(photos)}

@router.delete("/empty")
async def empty_discard(db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user)):
    """Permanently delete all discarded photos and unlink their files from
    disk. Failures on individual files are logged but don't abort the batch.
    """
    result = await db.execute(
        select(Photo).where(Photo.is_discarded == True, Photo.user_id == current_user.id)
    )
    photos = result.scalars().all()
    return await _permanently_delete(db, photos)


@router.delete("")
async def delete_discarded(
    photo_ids: list[str] = Body(..., embed=True),
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
):
    """Permanently delete a specific subset of discarded photos. The photos
    must already be in the discard pile — non-discarded ids are skipped so
    this can never bypass the soft-delete safety net.
    """
    if not photo_ids:
        return {"status": "success", "deleted": 0, "file_errors": 0}
    result = await db.execute(
        select(Photo).where(
            and_(Photo.id.in_(photo_ids), Photo.is_discarded == True, Photo.user_id == current_user.id)
        )
    )
    photos = result.scalars().all()
    return await _permanently_delete(db, photos)


async def _permanently_delete(db: AsyncSession, photos: list[Photo]) -> dict:
    """Shared helper: unlink files for the given photos and delete their
    rows. Per-file errors are counted but don't abort the batch.
    """
    deleted = 0
    file_errors = 0
    for photo in photos:
        try:
            if photo.filepath and os.path.exists(photo.filepath):
                os.unlink(photo.filepath)
        except OSError as e:
            file_errors += 1
            logger.error(f"Failed to unlink {photo.filepath}: {e}")
        await db.delete(photo)
        deleted += 1

    await db.commit()
    return {
        "status": "success",
        "deleted": deleted,
        "file_errors": file_errors,
    }
