# utils/design_helper.py
import os
import re
import uuid
from io import BytesIO
from urllib.parse import urlparse, parse_qs

import httpx
from PIL import Image, UnidentifiedImageError

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DESIGN_DIR = os.path.join(BASE_DIR, "design")
DESIGN_PUBLIC_PREFIX = "/pod-api/design"

os.makedirs(DESIGN_DIR, exist_ok=True)


def _extract_google_drive_file_id(url: str) -> str:
    raw = str(url or "").strip()
    if not raw:
        return ""

    patterns = [
        r"/file/d/([a-zA-Z0-9_-]+)",
        r"[?&]id=([a-zA-Z0-9_-]+)",
        r"/d/([a-zA-Z0-9_-]+)",
    ]

    for pattern in patterns:
        match = re.search(pattern, raw)
        if match:
            return match.group(1)

    return ""

def _is_dropbox_url(url: str) -> bool:
    host = (urlparse(str(url or "").strip()).netloc or "").lower()
    return "dropbox.com" in host or "dropboxusercontent.com" in host


def _build_dropbox_candidate_urls(url: str) -> list[str]:
    raw = str(url or "").strip()
    if not raw:
        return []

    parsed = urlparse(raw)
    query = parse_qs(parsed.query)

    candidates = []

    # Trường hợp đã là direct/raw host
    if "dropboxusercontent.com" in parsed.netloc.lower():
        candidates.append(raw)

    # Link share chuẩn của dropbox.com
    if "dropbox.com" in parsed.netloc.lower():
        # ép dl=1
        query["dl"] = ["1"]
        rebuilt_query = "&".join(
            f"{key}={value}"
            for key, values in query.items()
            for value in values
        )
        direct_url = parsed._replace(query=rebuilt_query).geturl()
        candidates.append(direct_url)

        # thêm bản raw=1
        query_raw = dict(query)
        query_raw["raw"] = ["1"]
        rebuilt_query_raw = "&".join(
            f"{key}={value}"
            for key, values in query_raw.items()
            for value in values
        )
        raw_url = parsed._replace(query=rebuilt_query_raw).geturl()
        candidates.append(raw_url)

    candidates.append(raw)

    seen = set()
    result = []
    for item in candidates:
        if item and item not in seen:
            seen.add(item)
            result.append(item)

    return result

def _build_candidate_urls(url: str) -> list[str]:
    raw = str(url or "").strip()
    if not raw:
        return []

    file_id = _extract_google_drive_file_id(raw)

    if file_id:
        candidates = [
            f"https://drive.google.com/uc?export=download&id={file_id}",
            f"https://drive.google.com/thumbnail?id={file_id}&sz=w2000",
            raw,
        ]
    elif _is_dropbox_url(raw):
        candidates = _build_dropbox_candidate_urls(raw)
    else:
        candidates = [raw]

    seen = set()
    result = []
    for item in candidates:
        if item and item not in seen:
            seen.add(item)
            result.append(item)

    return result


def is_local_design_value(value: str) -> bool:
    raw = str(value or "").strip()
    if not raw:
        return False

    return (
        raw.startswith("/design/")
        or raw.startswith("/pod-api/design/")
        or raw.startswith("design/")
        or "/pod-api/design/" in raw
    )


def ensure_design_local(design_url: str, filename_prefix: str = "design") -> dict:
    raw = str(design_url or "").strip()

    if not raw:
        return {
            "success": False,
            "publicUrl": "",
            "reason": "DESIGN_MISSING",
            "message": "Thiếu ảnh thiết kế (Design URL).",
        }

    if is_local_design_value(raw):
        if raw.startswith("design/"):
            raw = f"/{raw}"

        if raw.startswith("/design/"):
            raw = f"/pod-api{raw}"

        return {
            "success": True,
            "publicUrl": raw,
            "reason": "",
            "message": "",
        }

    headers = {
        "User-Agent": "Mozilla/5.0",
        "Accept": "image/*,*/*;q=0.8",
    }

    last_message = "Không tải được ảnh từ Design URL."

    for candidate_url in _build_candidate_urls(raw):
        try:
            with httpx.Client(
                timeout=20.0,
                follow_redirects=True,
                headers=headers,
            ) as client:
                response = client.get(candidate_url)

            if response.status_code >= 400:
                last_message = f"Không tải được ảnh từ Design URL (HTTP {response.status_code})."
                continue

            content = response.content
            if not content:
                last_message = "Design URL không trả về dữ liệu ảnh."
                continue

            image = Image.open(BytesIO(content))
            image.load()

            # luôn lưu png để đỡ đau đầu vụ format/mode
            if image.mode not in ("RGB", "RGBA"):
                image = image.convert("RGBA")

            file_name = f"{filename_prefix}_{uuid.uuid4().hex[:12]}.png"
            save_path = os.path.join(DESIGN_DIR, file_name)

            image.save(save_path, format="PNG")

            return {
                "success": True,
                "publicUrl": f"{DESIGN_PUBLIC_PREFIX}/{file_name}",
                "reason": "",
                "message": "",
            }

        except UnidentifiedImageError:
            last_message = (
                "Design URL không phải ảnh công khai hoặc link chia sẻ chưa cho phép truy cập trực tiếp."
            )
        except Exception as e:
            last_message = f"Không tải được ảnh từ Design URL: {str(e)}"

    reason = (
        "DESIGN_NOT_PUBLIC"
        if any(keyword in last_message.lower() for keyword in ["public", "trực tiếp", "không phải ảnh công khai"])
        else "DESIGN_DOWNLOAD_FAILED"
    )

    return {
        "success": False,
        "publicUrl": "",
        "reason": reason,
        "message": last_message,
    }