# -*- coding: utf-8 -*-
"""Azure Blob Storage 업로더 (ADO2 방식 슬림 포팅).

SDK 없이 SAS 토큰을 붙여 REST PUT 한다(aiohttp). 컨테이너가 공개 읽기이므로
재생 URL엔 SAS가 없고, 업로드에만 write SAS가 필요하다. SAS 미설정 시 비활성.

blob 경로: {BASE_URL}/{PREFIX}/{owner}/{job_id}/video/{파일명}
DB(Content.video)엔 SAS 없는 공개 URL을 저장한다.
"""
import re
from pathlib import Path

import aiohttp

from .config import settings

_UPLOAD_TIMEOUT = aiohttp.ClientTimeout(total=180, connect=10)
_SANITIZE_RE = re.compile(r"[^A-Za-z0-9._-]+")


def enabled() -> bool:
    return settings.azure_blob_enabled


def sanitize_filename(name: str) -> str:
    """URL·blob 안전 파일명(한글/공백/특수문자 → '_'). 확장자 유지."""
    stem = Path(name).stem
    ext = Path(name).suffix.lower()
    stem = _SANITIZE_RE.sub("_", stem).strip("_") or "video"
    return f"{stem}{ext}"


def _blob_path(owner_uuid: str | None, job_id: str, filename: str) -> str:
    owner = owner_uuid or "public"
    fn = sanitize_filename(filename)
    return f"{settings.AZURE_BLOB_PREFIX}/{owner}/{job_id}/video/{fn}"


def public_url(owner_uuid: str | None, job_id: str, filename: str) -> str:
    return f"{settings.AZURE_BLOB_BASE_URL.rstrip('/')}/{_blob_path(owner_uuid, job_id, filename)}"


async def upload_video(local_path: Path, owner_uuid: str | None, job_id: str) -> str | None:
    """mp4를 블롭에 업로드하고 공개 URL 반환. 실패/비활성 시 None."""
    if not enabled() or not local_path.is_file():
        return None
    blob = _blob_path(owner_uuid, job_id, local_path.name)
    sas = (settings.AZURE_BLOB_SAS_TOKEN or "").strip("?'\"")
    upload_url = f"{settings.AZURE_BLOB_BASE_URL.rstrip('/')}/{blob}?{sas}"
    headers = {"Content-Type": "video/mp4", "x-ms-blob-type": "BlockBlob"}
    try:
        data = local_path.read_bytes()
        async with aiohttp.ClientSession(timeout=_UPLOAD_TIMEOUT) as s:
            async with s.put(upload_url, data=data, headers=headers) as r:
                if r.status in (200, 201):
                    return f"{settings.AZURE_BLOB_BASE_URL.rstrip('/')}/{blob}"
                body = (await r.text())[:300]
                print(f"[blob] upload failed {r.status}: {body}")
                return None
    except Exception as e:                                    # 네트워크/타임아웃 — fallback
        print(f"[blob] upload error: {type(e).__name__}: {e}")
        return None
