"""Media and links CRUD endpoints."""
from __future__ import annotations

import uuid

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

from app.dependencies import get_current_user, get_db_session, get_storage_service
from app.db.repositories.media import MediaRepository
from app.schemas.media import MediaItemResponse, LinkResponse, PresignedUrlResponse
from app.services.storage import StorageService

router = APIRouter(tags=["media"])


# ── Media ─────────────────────────────────────────────────────────────────────

@router.get("/media", response_model=list[MediaItemResponse])
async def list_media(
    limit: int = 20,
    offset: int = 0,
    db: AsyncSession = Depends(get_db_session),
    current_user=Depends(get_current_user),
) -> list[MediaItemResponse]:
    repo = MediaRepository(db)
    items = await repo.list_for_user(current_user.id, limit=limit, offset=offset)
    return [MediaItemResponse.model_validate(item) for item in items]


@router.get("/media/{item_id}", response_model=MediaItemResponse)
async def get_media(
    item_id: uuid.UUID,
    db: AsyncSession = Depends(get_db_session),
    current_user=Depends(get_current_user),
) -> MediaItemResponse:
    repo = MediaRepository(db)
    item = await repo.get_media_item(item_id)
    if not item or item.user_id != current_user.id:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found")
    return MediaItemResponse.model_validate(item)


@router.get("/media/{item_id}/download", response_model=PresignedUrlResponse)
async def get_download_url(
    item_id: uuid.UUID,
    db: AsyncSession = Depends(get_db_session),
    current_user=Depends(get_current_user),
    storage: StorageService = Depends(get_storage_service),
) -> PresignedUrlResponse:
    repo = MediaRepository(db)
    item = await repo.get_media_item(item_id)
    if not item or item.user_id != current_user.id:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found")
    if not item.s3_key:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="No media file")
    url = await storage.generate_presigned_url(item.s3_key, expires_in=900)
    return PresignedUrlResponse(url=url, expires_in=900)


@router.delete("/media/{item_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_media(
    item_id: uuid.UUID,
    db: AsyncSession = Depends(get_db_session),
    current_user=Depends(get_current_user),
    storage: StorageService = Depends(get_storage_service),
) -> None:
    repo = MediaRepository(db)
    item = await repo.get_media_item(item_id)
    if not item or item.user_id != current_user.id:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found")
    # Delete S3 objects
    if item.s3_key:
        await storage.delete_object(item.s3_key)
    if item.thumbnail_s3_key:
        await storage.delete_object(item.thumbnail_s3_key)
    # Hard delete from DB (cascades to entity_tags, ai_analyses)
    await db.delete(item)
    await db.commit()


# ── Links ─────────────────────────────────────────────────────────────────────

@router.get("/links", response_model=list[LinkResponse])
async def list_links(
    limit: int = 20,
    offset: int = 0,
    db: AsyncSession = Depends(get_db_session),
    current_user=Depends(get_current_user),
) -> list[LinkResponse]:
    from sqlalchemy import select
    from app.db.models.media import Link
    result = await db.execute(
        select(Link)
        .where(Link.user_id == current_user.id)
        .order_by(Link.created_at.desc())
        .limit(limit)
        .offset(offset)
    )
    links = list(result.scalars().all())
    return [LinkResponse.model_validate(link) for link in links]


@router.get("/links/{link_id}", response_model=LinkResponse)
async def get_link(
    link_id: uuid.UUID,
    db: AsyncSession = Depends(get_db_session),
    current_user=Depends(get_current_user),
) -> LinkResponse:
    repo = MediaRepository(db)
    link = await repo.get_link(link_id)
    if not link or link.user_id != current_user.id:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found")
    return LinkResponse.model_validate(link)


@router.delete("/links/{link_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_link(
    link_id: uuid.UUID,
    db: AsyncSession = Depends(get_db_session),
    current_user=Depends(get_current_user),
) -> None:
    repo = MediaRepository(db)
    link = await repo.get_link(link_id)
    if not link or link.user_id != current_user.id:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found")
    await db.delete(link)
    await db.commit()
