import httpx
from fastapi import APIRouter, Depends, HTTPException
from fastapi.responses import Response
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.deps import get_db, get_tenant_by_domain
from app.core.models.product import Product
from app.core.models.tenant import Tenant
from app.core.services.plugin_helper import require_plugin
from app.plugins.product_attachments.models import ProductAttachment, ProductAttachmentType
from app.plugins.product_attachments.schemas import StoreProductAttachmentOut
from app.plugins.product_attachments.services import build_attachment_delivery_headers, list_store_product_attachments


async def _require_plugin(db: AsyncSession = Depends(get_db)) -> None:
    await require_plugin("product_attachments", db)


store_router = APIRouter(tags=["product_attachments_store"], dependencies=[Depends(_require_plugin)])


@store_router.get("/store/products/{product_id}/attachments", response_model=list[StoreProductAttachmentOut])
async def list_store_attachments(
    product_id: int,
    db: AsyncSession = Depends(get_db),
    tenant_id: int = Depends(get_tenant_by_domain),
):
    product_result = await db.execute(select(Product.id).where(Product.id == product_id, Product.tenant_id == tenant_id))
    if product_result.scalar_one_or_none() is None:
        raise HTTPException(status_code=404, detail="Product not found")
    return await list_store_product_attachments(db, tenant_id, product_id)


@store_router.get("/store/products/{product_id}/attachments/{attachment_id}/file")
async def deliver_store_specification(
    product_id: int,
    attachment_id: int,
    action: str = "open",
    store_domain: str | None = None,
    db: AsyncSession = Depends(get_db),
    tenant_id: int = Depends(get_tenant_by_domain),
):
    if action not in {"open", "download"}:
        raise HTTPException(status_code=400, detail="Invalid file action")
    if store_domain:
        domain = store_domain.split(":", 1)[0].lower().strip()
        tenant_result = await db.execute(select(Tenant.id, Tenant.status).where(Tenant.domain == domain))
        tenant = tenant_result.first()
        if tenant is None:
            raise HTTPException(status_code=404, detail="Store not found")
        if tenant.status == "suspended":
            raise HTTPException(status_code=403, detail="Store is suspended")
        tenant_id = tenant.id

    result = await db.execute(
        select(ProductAttachment)
        .join(ProductAttachmentType, ProductAttachment.type_id == ProductAttachmentType.id)
        .where(
            ProductAttachment.id == attachment_id,
            ProductAttachment.product_id == product_id,
            ProductAttachment.tenant_id == tenant_id,
            ProductAttachment.is_active == 1,
            ProductAttachmentType.tenant_id == tenant_id,
            ProductAttachmentType.code == "specification",
            ProductAttachmentType.is_active == 1,
        )
    )
    attachment = result.scalar_one_or_none()
    if attachment is None:
        raise HTTPException(status_code=404, detail="Specification not found")

    try:
        async with httpx.AsyncClient(timeout=20, follow_redirects=False) as client:
            file_response = await client.get(attachment.file_url)
    except httpx.HTTPError as exc:
        raise HTTPException(status_code=502, detail="Specification file is unavailable") from exc
    if file_response.status_code != 200:
        raise HTTPException(status_code=502, detail="Specification file is unavailable")

    return Response(
        content=file_response.content,
        media_type="application/pdf",
        headers=build_attachment_delivery_headers(attachment.file_url, action),
    )