from pathlib import Path


class Component:
    """Base class for self-contained UI components that contribute
    HTML, CSS, and JS to the viewer page."""

    def html(self) -> str:
        return ""

    def css(self) -> str:
        return ""

    def js(self) -> str:
        return ""


class QuitButton(Component):
    """The close button that posts to /quit, plus optional auto-quit on load."""

    def __init__(self, quit_on_load=False):
        self._quit_on_load = quit_on_load

    def html(self):
        return (
            '<form action="/quit" method="get" target="quit-frame" style="display:inline;">'
            '  <button type="submit" style="'
            "    display:inline-flex;align-items:center;justify-content:center;"
            "    width:24px;height:24px;border:none;border-radius:4px;"
            "    background:#eee;color:#333;text-decoration:none;"
            "    font-weight:bold;font-size:16px;"
            '    transition:background 0.2s ease;cursor:pointer;"'
            """    onmouseover="this.style.background='#ccc'" """
            """    onmouseout="this.style.background='#eee'" >"""
            '    <svg viewBox="0 0 10 10" width="12" height="12" fill="none"'
            '         stroke="currentColor" stroke-width="2">'
            '      <line x1="1" y1="1" x2="9" y2="9" />'
            '      <line x1="9" y1="1" x2="1" y2="9" />'
            "    </svg>"
            "  </button>"
            "</form>"
            '<iframe name="quit-frame" style="display:none;"></iframe>'
        )

    def js(self):
        if not self._quit_on_load:
            return ""
        return """
        window.addEventListener('load', function() {
            const quitButton = document.querySelector('form[action="/quit"] button');
            if (quitButton) {
                quitButton.click();
            }
        });
        """


class CaptureButton(Component):
    """Screenshot button that downloads the current model-viewer frame as PNG."""

    def html(self):
        return '<button id="capture-button">Capture</button>'

    def js(self):
        return """
        const modelViewer = document.getElementById("veux-viewer");

        async function downloadPosterToBlob() {
            const blob = await modelViewer.toBlob({ idealAspect: false });
            const url = URL.createObjectURL(blob);
            const a = document.createElement("a");
            a.href = url;
            a.download = "modelViewer_toBlob.png";
            a.click();
            URL.revokeObjectURL(url);
        }

        function downloadPosterToDataURL() {
            const url = modelViewer.toDataURL();
            const a = document.createElement("a");
            a.href = url;
            a.download = "modelViewer_toDataURL.png";
            a.click();
            URL.revokeObjectURL(url);
        }

        document.querySelector("#capture-button")
            .addEventListener("click", downloadPosterToBlob);
        """


class ControlPanel(Component):
    """Animation play/pause toggle. Reads controls.css and controls.js from disk."""

    def __init__(self, base_path):
        self._base = Path(base_path)

    def html(self):
        return """
        <div class="controls">
          <button id="toggle-animation">Pause</button>
        </div>
        """

    def css(self):
        with open(self._base / "controls.css", "r") as f:
            return f.read()

    def js(self):
        with open(self._base / "controls.js", "r") as f:
            return f.read()


class VeuxTable(Component):
    """Selection table UI. Reads from the mv/ subdirectory."""

    def __init__(self, base_path):
        self._base = Path(base_path)

    def html(self):
        with open(self._base / "mv" / "veux-select.html", "r") as f:
            return f.read()

    def css(self):
        with open(self._base / "mv" / "veux-select.css", "r") as f:
            return f.read()

    def js(self):
        with open(self._base / "mv" / "veux-select.js", "r") as f:
            return f.read()
