"""
Upload images from MDYPlateOrderStaging ("明道云开版暂存") to Tencent Cloud TIIA gallery.

Design goals:
- Reuse existing Tencent TIIA uploader: api_v1.utils.tencentcloud_tiia.upload_image_url_to_tencent_tiia
- Extract image URL from the MDY "开版图" Attachment field:
  - Prefer `original_file_full_path` (user requirement)
  - Fallback to `DownloadUrl`
- Per-image error isolation: keep going and return failures list
- Rate limit: default to settings.TENCENTCLOUD_TIIA_QPS (10 qps)
"""

from __future__ import annotations

from dataclasses import dataclass
from typing import Any

from django.conf import settings

from api_v1.models import MDYPlateOrderStaging
from api_v1.utils.tencentcloud_tiia import SimpleRateLimiter, upload_image_url_to_tencent_tiia
from flower.utils.mingdaoyun.relations import normalize_mdy_value


_MDY_PLATE_IMAGES_CONTROL_ID = "62d52f4b8d2972284492dd27"  # 开版图（Attachment）


@dataclass(frozen=True)
class _AttachmentUrlPickResult:
    url: str | None
    source_field: str | None


def _pick_attachment_url(item: dict[str, Any]) -> _AttachmentUrlPickResult:
    """
    Pick the best uploadable URL from a single MDY Attachment item dict.

    Priority (per user requirement):
    1) original_file_full_path / original_file_path
    2) DownloadUrl / download_url
    """
    # 1) original_file_full_path (observed in real data)
    for k in ("original_file_full_path", "original_file_path"):
        v = item.get(k)
        if isinstance(v, str) and v.strip():
            return _AttachmentUrlPickResult(url=v.strip(), source_field=k)

    # 2) DownloadUrl (observed in real data; note the exact case)
    for k in ("DownloadUrl", "download_url", "downloadUrl"):
        v = item.get(k)
        if isinstance(v, str) and v.strip():
            return _AttachmentUrlPickResult(url=v.strip(), source_field=k)

    return _AttachmentUrlPickResult(url=None, source_field=None)


def _extract_plate_image_attachment_items(staging: MDYPlateOrderStaging) -> list[dict[str, Any]]:
    raw = staging.raw if isinstance(staging.raw, dict) else {}
    value = normalize_mdy_value(raw.get(_MDY_PLATE_IMAGES_CONTROL_ID))

    if not value:
        return []
    if isinstance(value, dict):
        return [value]
    if isinstance(value, list):
        out: list[dict[str, Any]] = []
        for x in value:
            if isinstance(x, dict):
                out.append(x)
        return out
    return []


def upload_mdy_plate_order_staging_plate_images_to_tencent_tiia(
    *,
    staging: MDYPlateOrderStaging,
    rate_limiter: SimpleRateLimiter | None = None,
    dry_run: bool = False,
) -> dict[str, Any]:
    """
    Upload "开版图" images for a single staging record.

    EntityId:
    - Use `mdy_rowid` (stable unique string).
    """
    entity_id = str(staging.mdy_rowid)
    items = _extract_plate_image_attachment_items(staging)

    failures: list[dict[str, Any]] = []
    successes: list[dict[str, Any]] = []

    for idx, item in enumerate(items):
        picked = _pick_attachment_url(item)
        if not picked.url:
            failures.append(
                {
                    "index": idx,
                    "reason": "missing_url",
                    "mdy_keys": sorted(item.keys()),
                }
            )
            continue

        try:
            if rate_limiter is not None:
                rate_limiter.wait()
            if dry_run:
                resp = {"dry_run": True}
            else:
                # Store the original URL in CustomContent (default behavior if not passed).
                resp = upload_image_url_to_tencent_tiia(
                    image_url=picked.url,
                    entity_id=entity_id,
                    custom_content=picked.url,
                )
            successes.append(
                {
                    "index": idx,
                    "source_field": picked.source_field,
                    "image_url": picked.url,
                    "resp": resp,
                }
            )
        except Exception as exc:
            failures.append(
                {
                    "index": idx,
                    "source_field": picked.source_field,
                    "image_url": picked.url,
                    "error": str(exc),
                }
            )

    return {
        "mdy_rowid": staging.mdy_rowid,
        "staging_id": staging.id,
        "entity_id": entity_id,
        "total": len(items),
        "success_count": len(successes),
        "failure_count": len(failures),
        "successes": successes,
        "failures": failures,
    }


def build_default_tiia_rate_limiter() -> SimpleRateLimiter:
    qps = float(getattr(settings, "TENCENTCLOUD_TIIA_QPS", 10) or 10)
    return SimpleRateLimiter(qps=qps)

