from collections.abc import Iterable
from typing import Any
from urllib.parse import quote, urlparse

from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.plugins.product_attachments.models import ProductAttachment, ProductAttachmentType
from app.plugins.product_attachments.schemas import StoreProductAttachmentOut


def build_attachment_delivery_headers(file_url: str, action: str) -> dict[str, str]:
    filename = urlparse(file_url).path.rsplit("/", 1)[-1] or "specification.pdf"
    disposition = "attachment" if action == "download" else "inline"
    return {
        "Content-Disposition": f"{disposition}; filename*=UTF-8''{quote(filename)}",
        "X-Content-Type-Options": "nosniff",
    }


def _get_attr(obj: Any, key: str, default: Any = None) -> Any:
    if isinstance(obj, dict):
        return obj.get(key, default)
    return getattr(obj, key, default)


def map_aqua_attachment_slots(
    attachments: Iterable[Any],
    specification_type_code: str = "specification",
    manual_type_code: str = "manual",
) -> dict[str, str]:
    result = {"specificationUrl": "", "maunalUrl": ""}
    for attachment in attachments:
        type_code = _get_attr(attachment, "type_code")
        file_url = _get_attr(attachment, "file_url", "") or ""
        if not file_url:
            continue
        if type_code == specification_type_code and not result["specificationUrl"]:
            result["specificationUrl"] = file_url
        if type_code == manual_type_code and not result["maunalUrl"]:
            result["maunalUrl"] = file_url
    return result


async def list_store_product_attachments(
    db: AsyncSession,
    tenant_id: int,
    product_id: int,
) -> list[StoreProductAttachmentOut]:
    result = await db.execute(
        select(ProductAttachment, ProductAttachmentType)
        .join(ProductAttachmentType, ProductAttachment.type_id == ProductAttachmentType.id)
        .where(
            ProductAttachment.tenant_id == tenant_id,
            ProductAttachment.product_id == product_id,
            ProductAttachment.is_active == 1,
            ProductAttachmentType.tenant_id == tenant_id,
            ProductAttachmentType.is_active == 1,
        )
        .order_by(ProductAttachmentType.sort_order, ProductAttachment.sort_order, ProductAttachment.id)
    )
    rows: list[StoreProductAttachmentOut] = []
    for attachment, type_obj in result.all():
        rows.append(
            StoreProductAttachmentOut(
                id=attachment.id,
                type_code=type_obj.code,
                type_label=type_obj.label,
                title=attachment.title or type_obj.label,
                file_url=attachment.file_url,
                mime_type=attachment.mime_type,
                file_size=attachment.file_size,
                sort_order=attachment.sort_order,
            )
        )
    return rows
