from django import forms
from django.utils.safestring import mark_safe
from django.utils.html import format_html
from django.urls import reverse
from ..models.images import ImageLibrary


class ImageLibraryWidget(forms.Select):
    """
    Custom widget for selecting images from the library with thumbnails.
    """

    def __init__(self, attrs=None, choices=(), show_thumbnails=True):
        self.show_thumbnails = show_thumbnails
        super().__init__(attrs, choices)

    def format_value(self, value):
        """
        Format the selected value for display.
        """
        if value is None:
            return ""
        return str(value)

    def render(self, name, value, attrs=None, renderer=None):
        """
        Render the widget with thumbnails.
        """
        if attrs is None:
            attrs = {}

        # Add CSS class for styling
        attrs["class"] = attrs.get("class", "") + " image-library-select"

        # Get all images for the select options
        images = ImageLibrary.objects.all().order_by("name")

        # Build choices with thumbnails
        choices = [("", "--- Select an image ---")]
        for image in images:
            thumbnail_html = ""
            if self.show_thumbnails and image.image:
                thumbnail_html = format_html(
                    ' <img src="{}" style="width: 20px; height: 20px; object-fit: cover; margin-left: 5px; vertical-align: middle;" />',
                    image.image.url,
                )

            choice_text = (
                f"{image.name} ({image.get_category_display()}){thumbnail_html}"
            )
            choices.append((image.pk, choice_text))

        # Build the select element
        select_html = format_html(
            '<select name="{}" id="{}"{}>{}</select>',
            name,
            attrs.get("id", ""),
            self._build_attrs_string(attrs),
            self._build_options(choices, value),
        )

        # Add preview area
        preview_html = ""
        if value:
            try:
                image = ImageLibrary.objects.get(pk=value)
                preview_html = format_html(
                    '<div class="image-preview" style="margin-top: 10px;">'
                    '<img src="{}" style="max-width: 200px; max-height: 200px; border: 1px solid #ddd; border-radius: 4px;" />'
                    '<p style="margin-top: 5px; font-size: 12px; color: #666;">{} - {}x{} - {}</p>'
                    "</div>",
                    image.image.url,
                    image.name,
                    image.width or "?",
                    image.height or "?",
                    image.get_file_size_display(),
                )
            except ImageLibrary.DoesNotExist:
                pass

        # Add JavaScript for preview updates
        js_html = format_html(
            "<script>"
            'document.addEventListener("DOMContentLoaded", function() {{'
            '    const select = document.getElementById("{}");\n'
            '    const previewDiv = select.parentNode.querySelector(".image-preview");\n'
            '    select.addEventListener("change", function() {{'
            "        const imageId = this.value;\n"
            "        if (imageId) {{"
            '            fetch("/admin/services/imagelibrary/" + imageId + "/preview/")'
            "            .then(response => response.json())"
            "            .then(data => {{"
            "                if (previewDiv) {{"
            "                    previewDiv.innerHTML = data.html;\n"
            "                }}"
            "            }});\n"
            "        }} else {{"
            "            if (previewDiv) {{"
            '                previewDiv.innerHTML = "";\n'
            "            }}"
            "        }}"
            "    }});\n"
            "}});\n"
            "</script>",
            attrs.get("id", ""),
        )

        return mark_safe(select_html + preview_html + js_html)

    def _build_attrs_string(self, attrs):
        """
        Build HTML attributes string.
        """
        attr_parts = []
        for key, value in attrs.items():
            if key != "id":  # id is handled separately
                attr_parts.append(f'{key}="{value}"')
        return " " + " ".join(attr_parts) if attr_parts else ""

    def _build_options(self, choices, selected_value):
        """
        Build option elements for the select.
        """
        options = []
        for value, text in choices:
            selected = "selected" if str(value) == str(selected_value) else ""
            options.append(f'<option value="{value}" {selected}>{text}</option>')
        return "".join(options)


class ImageLibraryField(forms.ModelChoiceField):
    """
    Custom form field for selecting images from the library.
    """

    def __init__(self, queryset=None, widget=None, show_thumbnails=True, **kwargs):
        if queryset is None:
            queryset = ImageLibrary.objects.all()

        if widget is None:
            widget = ImageLibraryWidget(show_thumbnails=show_thumbnails)

        super().__init__(queryset=queryset, widget=widget, **kwargs)

    def label_from_instance(self, obj):
        """
        Return the label for an image instance.
        """
        return f"{obj.name} ({obj.get_category_display()})"
