"""
Decode base64 profile images and persist under local_upload_dir.
"""
import base64
import re
import uuid
from pathlib import Path
from typing import Optional, Tuple

from app.config import settings

MAX_PROFILE_IMAGE_BYTES = 5 * 1024 * 1024

_PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent


def _uploads_dir() -> Path:
    rel = settings.local_upload_dir.lstrip("./")
    return _PROJECT_ROOT / rel


def parse_base64_image(value: str) -> Tuple[bytes, str]:
    """
    Decode standard base64 or data URL (data:image/...;base64,...).
    Returns (raw_bytes, extension) where extension is .jpg, .png, or .webp.
    """
    s = (value or "").strip()
    if not s:
        raise ValueError("profile_picture_base64 is empty")

    mime: Optional[str] = None
    if s.startswith("data:"):
        header, sep, b64_part = s.partition(",")
        if not sep:
            raise ValueError("Invalid profile picture data URL")
        if ";base64" not in header.lower():
            raise ValueError("Profile picture data URL must be base64-encoded")
        mime_match = re.match(r"data:([^;]+)", header, re.I)
        if mime_match:
            mime = mime_match.group(1).strip().lower()
        payload = b64_part.strip()
    else:
        payload = s

    try:
        raw = base64.b64decode(payload, validate=True)
    except Exception as exc:
        raise ValueError("Invalid base64 image data") from exc

    if len(raw) > MAX_PROFILE_IMAGE_BYTES:
        raise ValueError("Profile image too large (max 5MB)")

    ext = _extension_from_mime_or_magic(raw, mime)
    return raw, ext


def _extension_from_mime_or_magic(raw: bytes, mime: Optional[str]) -> str:
    if mime:
        m = {
            "image/jpeg": ".jpg",
            "image/jpg": ".jpg",
            "image/png": ".png",
            "image/webp": ".webp",
        }.get(mime)
        if m and _magic_matches(raw, m):
            return m
        if m:
            raise ValueError("Image content does not match declared type")

    if raw.startswith(b"\xff\xd8\xff"):
        return ".jpg"
    if raw.startswith(b"\x89PNG\r\n\x1a\n"):
        return ".png"
    if raw.startswith(b"RIFF") and len(raw) >= 12 and raw[8:12] == b"WEBP":
        return ".webp"
    raise ValueError("Unsupported image type (use JPEG, PNG, or WebP)")


def _magic_matches(raw: bytes, ext: str) -> bool:
    if ext == ".jpg":
        return raw.startswith(b"\xff\xd8\xff")
    if ext == ".png":
        return raw.startswith(b"\x89PNG\r\n\x1a\n")
    if ext == ".webp":
        return raw.startswith(b"RIFF") and len(raw) >= 12 and raw[8:12] == b"WEBP"
    return False


def save_profile_picture_from_base64(user_id: int, value: str) -> str:
    """Validate base64 / data-URL, persist file, return stored URL path."""
    raw, ext = parse_base64_image(value)
    return store_profile_picture(user_id, raw, ext)


def store_profile_picture(user_id: int, image_bytes: bytes, ext: str) -> str:
    """
    Write image to local storage and return a URL path suitable for profile_picture.
    """
    root = _uploads_dir()
    dest_dir = root / "profiles" / str(user_id)
    dest_dir.mkdir(parents=True, exist_ok=True)
    name = f"{uuid.uuid4().hex}{ext}"
    path = dest_dir / name
    path.write_bytes(image_bytes)
    return f"/uploads/profiles/{user_id}/{name}"
