"""Endpoint upload gambar untuk editor TinyMCE.

Dipakai oleh tiga jalur di editor: tombol upload, drag-and-drop, dan tempel
(paste) dari clipboard. Token CSRF dikirim oleh handler JS lewat header
X-CSRFToken, jadi view ini tetap terlindungi seperti form biasa.
"""

import uuid
from datetime import datetime

from django.contrib.auth.decorators import login_required
from django.core.files.storage import default_storage
from django.http import JsonResponse
from django.urls import reverse_lazy
from django.views.decorators.http import require_POST
from PIL import Image, UnidentifiedImageError

MAX_UPLOAD_SIZE = 5 * 1024 * 1024  # 5 MB
ALLOWED_EXTENSIONS = {"jpg", "jpeg", "png", "gif", "webp", "avif", "svg"}
# SVG tidak bisa diverifikasi Pillow dan bisa memuat script — tidak diizinkan.
RASTER_EXTENSIONS = ALLOWED_EXTENSIONS - {"svg"}


def _error(message, status=400):
    # TinyMCE menampilkan isi key "message" ini ke pengguna.
    return JsonResponse({"error": {"message": message, "remove": True}}, status=status)


@login_required(login_url=reverse_lazy("dashboard:login"))
@require_POST
def upload_image(request):
    upload = request.FILES.get("file")
    if upload is None:
        return _error("Tidak ada berkas yang dikirim.")

    if upload.size > MAX_UPLOAD_SIZE:
        mb = MAX_UPLOAD_SIZE // (1024 * 1024)
        return _error(f"Ukuran gambar maksimal {mb} MB.")

    extension = upload.name.rsplit(".", 1)[-1].lower() if "." in upload.name else ""
    if extension not in RASTER_EXTENSIONS:
        allowed = ", ".join(sorted(RASTER_EXTENSIONS))
        return _error(f"Format tidak didukung. Gunakan: {allowed}.")

    # Jangan percaya nama berkas atau content-type — buktikan isinya memang gambar.
    try:
        Image.open(upload).verify()
    except (UnidentifiedImageError, OSError, ValueError):
        return _error("Berkas ini bukan gambar yang valid.")
    finally:
        upload.seek(0)

    today = datetime.now()
    filename = f"{uuid.uuid4().hex}.{extension}"
    path = default_storage.save(f"uploads/{today:%Y/%m}/{filename}", upload)

    return JsonResponse({"location": default_storage.url(path)})
