"""MediaAsset router — /api/media."""
import io
import uuid
import zipfile

from fastapi import APIRouter, Depends, HTTPException, Query
from fastapi.responses import StreamingResponse
from sqlalchemy.ext.asyncio import AsyncSession

from app.database import get_db
from app.domains.media.models import MediaAssetType
from app.domains.media.schemas import MediaAssetOut
from app.domains.media import service

router = APIRouter(prefix="/api/media", tags=["media"])


@router.get("/", response_model=list[MediaAssetOut])
async def list_assets(
    product_id: uuid.UUID | None = None,
    order_line_id: uuid.UUID | None = None,
    asset_type: MediaAssetType | None = None,
    skip: int = Query(0, ge=0),
    limit: int = Query(50, ge=1, le=500),
    db: AsyncSession = Depends(get_db),
):
    assets = await service.list_media_assets(
        db,
        product_id=product_id,
        order_line_id=order_line_id,
        asset_type=asset_type,
        skip=skip,
        limit=limit,
    )
    for a in assets:
        a.download_url = service.get_download_url(a)
    return assets


@router.get("/{asset_id}", response_model=MediaAssetOut)
async def get_asset(asset_id: uuid.UUID, db: AsyncSession = Depends(get_db)):
    asset = await service.get_media_asset(db, asset_id)
    if not asset:
        raise HTTPException(404, "Asset not found")
    asset.download_url = service.get_download_url(asset)
    return asset


@router.get("/{asset_id}/download")
async def download_asset(asset_id: uuid.UUID, db: AsyncSession = Depends(get_db)):
    from fastapi.responses import RedirectResponse
    asset = await service.get_media_asset(db, asset_id)
    if not asset:
        raise HTTPException(404, "Asset not found")
    url = service.get_download_url(asset)
    if url:
        return RedirectResponse(url)
    raise HTTPException(404, "File not available")


@router.post("/zip")
async def zip_download(
    asset_ids: list[uuid.UUID],
    db: AsyncSession = Depends(get_db),
):
    assets = []
    for aid in asset_ids:
        a = await service.get_media_asset(db, aid)
        if a:
            assets.append(a)
    if not assets:
        raise HTTPException(404, "No assets found")

    def generate():
        buf = io.BytesIO()
        with zipfile.ZipFile(buf, "w", zipfile.ZIP_DEFLATED) as zf:
            from app.core.storage import get_storage
            storage = get_storage()
            for a in assets:
                ext = (a.mime_type or "").split("/")[-1] or "bin"
                fname = f"{a.asset_type.value}_{a.id}.{ext}"
                try:
                    data = storage.download_bytes(a.storage_key)
                    zf.writestr(fname, data)
                except Exception:
                    pass
        yield buf.getvalue()

    return StreamingResponse(
        generate(),
        media_type="application/zip",
        headers={"Content-Disposition": "attachment; filename=media-export.zip"},
    )


@router.delete("/{asset_id}")
async def archive_asset(asset_id: uuid.UUID, db: AsyncSession = Depends(get_db)):
    asset = await service.archive_media_asset(db, asset_id)
    if not asset:
        raise HTTPException(404, "Asset not found")
    return {"ok": True}
