<?php
namespace Components\Resources;

use Components\Base;
use Components\Dropdown;
use Components\Legacy\LegacyRouter;
use Components\Ui\SelectableCard;
use Components\Ui\Card;
use Components\Ui\Tooltip;

class TemplateCard
{
    private static bool $scriptsRendered = false;

    /**
     * Render the necessary scripts for thumbnail generation.
     * Only renders once per request.
     */
    public static function renderScripts(string $ajaxUrl): string
    {
        if (self::$scriptsRendered) {
            return '';
        }
        self::$scriptsRendered = true;

//        $html2canvasUrl = (defined('BEEZUI_WEB_ROOT') ? BEEZUI_WEB_ROOT : '') . 'appui/assets/js/html2canvas-pro.min.js?ver=' . \mh_cfg('MAILBEEZ_VERSION');

        ob_start();
        ?>

<!--        <script type="text/javascript" src="--><?php //= $html2canvasUrl ?><!--"></script>-->
        <script type="text/javascript">
            var ajaxUrl = '<?= $ajaxUrl ?>';
            var thumbnailQueue = [];
            var activeThumbnailProcesses = 0;
            var maxThumbnailProcesses = 5;

            var thumbnailObserver = (typeof IntersectionObserver !== 'undefined') ? new IntersectionObserver(function(entries) {
                entries.forEach(function(entry) {
                    if (entry.isIntersecting) {
                        var el = entry.target;
                        thumbnailObserver.unobserve(el);
                        var id = el.id.replace('preview_', '');

                        // Prioritize this id in the queue if it's there
                        for (var i = 0; i < thumbnailQueue.length; i++) {
                            if (thumbnailQueue[i].id === id) {
                                var data = thumbnailQueue.splice(i, 1)[0];
                                thumbnailQueue.unshift(data);
                                break;
                            }
                        }
                        processThumbnailQueue();
                    }
                });
            }, { rootMargin: '200px' }) : null;

            function processThumbnailQueue() {
                if (thumbnailQueue.length === 0 || activeThumbnailProcesses >= maxThumbnailProcesses) return;

                if (typeof html2canvas === 'undefined') {
                    setTimeout(processThumbnailQueue, 200);
                    return;
                }

                activeThumbnailProcesses++;
                var data = thumbnailQueue.shift();

                generateThumbnail(data.id, data.maintemplate_id, data.content_module_id, data.loadurl, function() {
                    activeThumbnailProcesses--;
                    setTimeout(processThumbnailQueue, 100);
                });

                // If we have more capacity and items in the queue, start next one
                if (activeThumbnailProcesses < maxThumbnailProcesses && thumbnailQueue.length > 0) {
                    processThumbnailQueue();
                }
            }

            function updateThumbnail(id, maintemplate_id, content_module_id, loadurl) {
                var target = document.querySelector('#preview_' + id);
                if (!target) return;

                // Check if already in queue
                for (var i = 0; i < thumbnailQueue.length; i++) {
                    if (thumbnailQueue[i].id === id) return;
                }

                var data = {
                    id: id,
                    maintemplate_id: maintemplate_id,
                    content_module_id: content_module_id,
                    loadurl: loadurl
                };

                thumbnailQueue.push(data);

                if (thumbnailObserver) {
                    thumbnailObserver.observe(target);
                }

                processThumbnailQueue();
            }

            function refreshAllThumbnails(container) {
                // Clear the current queue to ensure we follow the DOM order of the found targets
                thumbnailQueue = [];

                var root = container || document;
                var targets = root.querySelectorAll('.emailthumbnail[data-generate-url]');
                targets.forEach(function(target) {
                    // Only refresh visible thumbnails to avoid unnecessary processing
                    // for elements in hidden tabs or other background pages.
                    if (target.offsetParent !== null) {
                        var id = target.getAttribute('data-preview-id');
                        var maintemplate_id = target.getAttribute('data-maintemplate-id');
                        var content_module_id = target.getAttribute('data-content-module-id');
                        var loadurl = target.getAttribute('data-generate-url');

                        if (loadurl) {
                            updateThumbnail(id, maintemplate_id, content_module_id, loadurl);
                        }
                    }
                });
            }

            function generateThumbnail(id, maintemplate_id, content_module_id, loadurl, callback) {
                var target = document.querySelector('#preview_' + id);
                if (target) {
                    var indicator = target.querySelector('.generating-indicator');
                    if (indicator) indicator.classList.remove('opacity-0');
                }

                var iframeId = 'screen_' + id;
                if (document.getElementById(iframeId)) {
                    if (callback) callback();
                    return;
                }

                var iframe = document.createElement('iframe');
                iframe.src = loadurl;
                iframe.id = iframeId;
                iframe.style.visibility = 'hidden';
                iframe.style.position = 'absolute';
                iframe.style.left = '-9999px';
                iframe.width = '740';

                iframe.onload = function() {
                    processThumbnail(iframe, '#preview_' + id, maintemplate_id, content_module_id, callback);
                };
                iframe.onerror = function() {
                    var target = document.querySelector('#preview_' + id);
                    if (target) {
                        var indicator = target.querySelector('.generating-indicator');
                        if (indicator) indicator.classList.add('opacity-0');
                    }
                    if (callback) callback();
                };
                document.body.appendChild(iframe);
            }

            function processThumbnail(el, targetSelector, maintemplate_id, content_module_id, callback) {
                try {
                    var iFrameBody = el.contentWindow.document.body;
                    html2canvas(iFrameBody).then(function (canvas) {
                        var image = new Image();
                        image.src = canvas.toDataURL("image/png");
                        image.style.width = '100%';
                        // Allow vertical overflow so we can animate preview scroll on hover.
                        image.className = 'w-full h-auto block transition-opacity duration-500 opacity-0 will-change-transform';

                        var target = document.querySelector(targetSelector);
                        if (target) {
                            var oldImg = target.querySelector('img');
                            if (oldImg) {
                                oldImg.onload = function() {
                                    try {
                                        target.dispatchEvent(new CustomEvent('preview-img-loaded', { bubbles: true }));
                                    } catch (e) {}
                                };
                                oldImg.src = image.src;
                            } else {
                                var placeholder = target.querySelector('.placeholder-content');
                                if (placeholder) placeholder.remove();

                                image.onload = function() {
                                    try {
                                        target.dispatchEvent(new CustomEvent('preview-img-loaded', { bubbles: true }));
                                    } catch (e) {}
                                };

                                target.prepend(image);
                                setTimeout(function() {
                                    image.classList.remove('opacity-0');
                                }, 10);

                                // In case the image is already cached/complete.
                                try {
                                    if (image.complete) {
                                        target.dispatchEvent(new CustomEvent('preview-img-loaded', { bubbles: true }));
                                    }
                                } catch (e) {}
                            }
                            var indicator = target.querySelector('.generating-indicator');
                            if (indicator) indicator.classList.add('opacity-0');

                            try {
                                target.dispatchEvent(new CustomEvent('preview-img-loaded', { bubbles: true }));
                            } catch (e) {}
                        }

                        var dataURL = canvas.toDataURL();
                        var finish = function() {
                            console.log('thumbnail saved');
                            setTimeout(function() {
                                if(el.parentNode) el.parentNode.removeChild(el);
                                if (callback) callback();
                            }, 500);
                        };

                        if (window.jQuery) {
                            jQuery.ajax({
                                type: "POST",
                                url: ajaxUrl,
                                data: {
                                    maintemplate_id: maintemplate_id,
                                    content_module_id: content_module_id,
                                    imgBase64: dataURL
                                }
                            }).always(finish);
                        } else {
                            fetch(ajaxUrl, {
                                method: 'POST',
                                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
                                body: 'maintemplate_id=' + encodeURIComponent(maintemplate_id) +
                                      '&content_module_id=' + encodeURIComponent(content_module_id) +
                                      '&imgBase64=' + encodeURIComponent(dataURL)
                            }).then(finish).catch(finish);
                        }
                    }).catch(function(e) {
                        console.error('html2canvas failed', e);
                        var target = document.querySelector(targetSelector);
                        if (target) {
                            var indicator = target.querySelector('.generating-indicator');
                            if (indicator) indicator.classList.add('opacity-0');
                        }
                        if (el.parentNode) el.parentNode.removeChild(el);
                        if (callback) callback();
                    });
                } catch (e) {
                    console.error('processThumbnail failed', e);
                    var target = document.querySelector(targetSelector);
                    if (target) {
                        var indicator = target.querySelector('.generating-indicator');
                        if (indicator) indicator.classList.add('opacity-0');
                    }
                    if (el.parentNode) el.parentNode.removeChild(el);
                    if (callback) callback();
                }
            }
        </script>

        <script type="text/javascript">
            // Alpine component: smoothly scroll a tall preview image within a fixed-aspect frame on hover.
            (function () {
                function registerTemplatePreviewScroller() {
                    try {
                        if (!window.Alpine || typeof Alpine.data !== 'function') return;
                        Alpine.data('templatePreviewScroller', function () {
                            return {
                                y: 0,
                                max: 0,
                                raf: null,
                                lastTs: null,
                                resetTimer: null,

                                // Speed: px per second
                                speed: 120,
                                // Return-to-top animation duration (ms)
                                resetDuration: 700,

                                imgEl() {
                                    return this.$el ? this.$el.querySelector('img') : null;
                                },

                                setTransition(enabled) {
                                    try {
                                        var img = this.imgEl();
                                        if (!img) return;
                                        img.style.transition = enabled ? ('transform ' + this.resetDuration + 'ms ease-out') : 'none';
                                    } catch (e) {}
                                },

                                recalc() {
                                    try {
                                        var img = this.imgEl();
                                        if (!img) {
                                            this.max = 0;
                                            return;
                                        }
                                        // Ensure image renders from top.
                                        img.style.transform = img.style.transform || 'translateY(0px)';

                                        var containerH = this.$el.clientHeight || 0;
                                        // Use offsetHeight: depends on computed width and image intrinsic ratio.
                                        var imgH = img.offsetHeight || 0;
                                        this.max = Math.max(0, imgH - containerH);
                                        if (this.y > this.max) this.y = this.max;
                                        if (this.max <= 0) {
                                            this.y = 0;
                                            this.apply();
                                        }
                                    } catch (e) {}
                                },

                                apply() {
                                    try {
                                        var img = this.imgEl();
                                        if (!img) return;
                                        img.style.transform = 'translateY(' + (-this.y) + 'px)';
                                    } catch (e) {}
                                },

                                start() {
                                    this.stop(false);
                                    this.recalc();
                                    if (!this.max || this.max <= 0) return;
                                    this.lastTs = null;

                                    // Disable transitions while animating via RAF
                                    this.setTransition(false);

                                    var self = this;
                                    var step = function (ts) {
                                        if (!self.raf) return;
                                        if (self.lastTs === null) self.lastTs = ts;
                                        var dt = ts - self.lastTs;
                                        self.lastTs = ts;

                                        // dt in ms
                                        var delta = (self.speed * dt) / 1000;
                                        self.y = Math.min(self.max, self.y + delta);
                                        self.apply();

                                        // Only scroll up while hovered. Stop at the bottom.
                                        if (self.y >= self.max) {
                                            cancelAnimationFrame(self.raf);
                                            self.raf = null;
                                            return;
                                        }

                                        self.raf = requestAnimationFrame(step);
                                    };
                                    this.raf = requestAnimationFrame(step);
                                },

                                stop(reset) {
                                    try {
                                        if (this.raf) {
                                            cancelAnimationFrame(this.raf);
                                            this.raf = null;
                                        }
                                        this.lastTs = null;

                                        if (this.resetTimer) {
                                            clearTimeout(this.resetTimer);
                                            this.resetTimer = null;
                                        }

                                        if (reset) {
                                            // Smoothly return to the initial (top) position on mouse leave.
                                            this.setTransition(true);
                                            this.y = 0;
                                            this.apply();

                                            var self = this;
                                            this.resetTimer = setTimeout(function () {
                                                // Clean up to avoid transitions interfering with hover RAF later.
                                                self.setTransition(false);
                                                self.resetTimer = null;
                                            }, this.resetDuration + 50);
                                        }
                                    } catch (e) {}
                                },

                                init() {
                                    var self = this;
                                    try {
                                        this.$nextTick(function () {
                                            self.setTransition(false);
                                            self.recalc();
                                        });
                                        window.addEventListener('resize', function () {
                                            self.recalc();
                                        }, { passive: true });
                                    } catch (e) {}
                                }
                            };
                        });
                    } catch (e) {}
                }

                if (window.Alpine && typeof Alpine.data === 'function') {
                    registerTemplatePreviewScroller();
                } else {
                    document.addEventListener('alpine:init', registerTemplatePreviewScroller, { once: true });
                }
            })();
        </script>
        <?php
        return ob_get_clean();
    }

    /**
     * Render a single template card.
     *
     * @param array $options {
     *     @var array $tpl The template data
     *     @var string $type The type of template ('basic', 'gallery', 'user')
     *     @var int $idx The index of the card in the list
     *     @var string $context The context ('module' or other)
     *     @var string $module The module code
     *     @var int $lng_id The language ID
     *     @var int $newsletter_id The newsletter ID
     *     @var int $flow_id The flow ID
     * }
     * @return string
     */
    public static function render(array $options): string
    {
        $tpl = $options['tpl'] ?? [];
        $type = $options['type'] ?? '';
        $idx = $options['idx'] ?? 0;

        $context = $options['context'] ?? 'module';
        $module = $options['module'] ?? '';
        $lngId = (int)($options['lng_id'] ?? 0);
        $newsletterId = (int)($options['newsletter_id'] ?? 0);
        $flowId = (int)($options['flow_id'] ?? 0);
        $content_module_id = $options['content_module_id'] ?? '';
        $isModal = (bool)($options['is_modal'] ?? false);
        $selectionMode = (string)($options['selection_mode'] ?? '');
        $onlyActions = $options['only_actions'] ?? [];
        if (!is_array($onlyActions)) {
            $onlyActions = [];
        }
        $maintemplate_id_short = $options['maintemplate_id'] ?? null;
        $importLabel = ($maintemplate_id_short !== null && $maintemplate_id_short !== 'MAIN')
            ? \mh_lng('UI_BUTTON_IMPORT_INTO_CURRENT', 'Import into Current')
            : \mh_lng('UI_BUTTON_IMPORT_INTO_MAIN', 'Import into Main');

        $templateId = $tpl['maintemplate_id'] ?? '';
        if ($context === 'module' && $templateId === 'MAIN' && !empty($tpl['content_module_id'])) {
            $templateId = $tpl['content_module_id'];
        }

        $scripts = SelectableCard::renderScripts();
        if (!self::$scriptsRendered) {
            $thumbnail_update_ajax_url = '';
            if (class_exists('\Components\Legacy\LegacyRouter')) {
                try {
                    $thumbnail_update_ajax_url = LegacyRouter::url('thumbnailUpdate', ['lng_id' => $lngId]);
                } catch (\Throwable $e) {
                }
            }
            $scripts .= self::renderScripts($thumbnail_update_ajax_url);
        }

        $selectUrl = $tpl['url_select'] ?? '';
        $selectedTemplateId = '';
        if ($context === 'newsletter') {
            $selectedTemplateId = (string)\mh_get('template_id', '');
            if ($selectedTemplateId === '') {
                $selectedTemplateId = (string)\mh_post('template_id', '');
            }
        }

        // Resolve the real template id to import for newsletters. The card-level
        // $templateId is the maintemplate_id (often 'MAIN'); the actual selectable
        // template lives in 'filepath' (gallery) or 'content_module_id' (user template).
        $selectTemplateId = $templateId;
        if ($context === 'newsletter') {
            if (!empty($tpl['filepath'])) {
                $selectTemplateId = (string)$tpl['filepath'];
            } elseif (!empty($tpl['content_module_id']) && $tpl['content_module_id'] !== 'false') {
                $selectTemplateId = (string)$tpl['content_module_id'];
            }
        }

        // When editing an existing newsletter ($newsletterId > 0) the gallery is used to
        // IMPORT a template into that newsletter via the confirm dialog (Select action),
        // not to start the create-new-newsletter wizard. Only treat cards as wizard
        // selection cards (whole-card click/double-click) during the create-new flow.
        $isNewsletterImport = $isModal && $context === 'newsletter' && $newsletterId > 0;
        $isNewsletterSelectionCard = $isModal && $context === 'newsletter' && !empty($selectUrl) && !$isNewsletterImport;
        $newsletterPrimaryActionAttrs = [];
        if ($isNewsletterSelectionCard) {
            $newsletterPrimaryActionAttrs = [
                'hx-get' => $selectUrl,
                'hx-target' => '#config-modal-body',
                'hx-push-url' => 'false',
            ];
        }

        $isNewsletterPreselected = $isNewsletterSelectionCard
            && $selectedTemplateId !== ''
            && $selectedTemplateId === (string)($tpl['filepath'] ?? '');

        $actions = [];

        $isCurrent = (bool)($tpl['is_current'] ?? false);
        if (!$isCurrent && $isModal && $context === 'module' && !empty($content_module_id)) {
            if (isset($tpl['content_module_id']) && $tpl['content_module_id'] === $content_module_id) {
                $isCurrent = true;
                $tpl['is_current'] = true;
            }
        }

        $isMainGallerySelectionCard = $selectionMode === 'create_main_from_gallery'
            && $context === 'main'
            && $type === 'gallery'
            && !$isCurrent;

        $mainGalleryPrimaryActionAttrs = [];
        if ($isMainGallerySelectionCard) {
            $mainGalleryPrimaryActionAttrs = [
                'hx-get' => \Components\Router::url('template_action_confirm', [
                    'confirm_action' => 'create_from_gallery',
                    'template_id' => $templateId,
                    'lng_id' => $lngId,
                    'context' => $context,
                    'module' => $module,
                    'content_module_id' => $content_module_id,
                    'partial' => 1,
                ]),
                'hx-target' => '#config-modal-body',
                'hx-swap' => 'innerHTML',
                'hx-push-url' => 'false',
            ];
        }

        if (!$isCurrent && $isModal && ($context === 'module' || $context === 'newsletter') && !empty($selectUrl)) {
            $actions[] = [
                'label' => \mh_lng('UI_BUTTON_TEMPLATE_SELECT', 'Select'),
                'attrs' => [
                    'command' => 'show-modal',
                    'commandfor' => 'confirm-modal',
                    'data-title' => \mh_lng('UI_BUTTON_TEMPLATE_SELECT', 'Select'),
                    'hx-get' => \Components\Router::url('template_action_confirm', [
                        'confirm_action' => 'select_template',
                        'template_id' => $selectTemplateId,
                        'lng_id' => $lngId,
                        'module' => $module,
                        'context' => $context,
                        'newsletter_id' => $newsletterId,
                        'flow_id' => $flowId,
                        'maintemplate_id' => $maintemplate_id_short,
                        'content_module_id' => $content_module_id,
                        'select_url' => $selectUrl,
                        'partial' => 1
                    ]),
                    'data-type' => 'warning',
                    'hx-target' => '#confirm-modal-body',
                    'hx-swap' => 'innerHTML',
                ],
                'icon' => Base::SVG_PLAY,
            ];
        }

        if ($context === 'newsletter' && !empty($tpl['filepath'])) {
            if (!$isModal) {
                $actions[] = [
                    'label' => \mh_lng('UI_BUTTON_CREATE_NEWSLETTER', 'Create Newsletter'),
                    'attrs' => [
                        'command' => 'show-modal',
                        'commandfor' => 'config-modal',
                        'data-title' => \mh_lng('UI_BUTTON_CREATE_NEWSLETTER', 'Create Newsletter'),
                        'data-size' => '5xl',
                        'data-dismissible' => 'false',
                        'hx-get' => \Components\Router::url('newsletter_audience_selection_modal', [
                            'partial' => 1,
                            'template_id' => $tpl['filepath'],
                            'page_mode' => 'newsletter',
                            'skip_template' => 1
                        ]),
                        'hx-target' => '#config-modal-body',
                        'hx-swap' => 'innerHTML',
                        'hx-push-url' => 'false',
                    ],
                    'icon' => Base::SVG_PLUS,
                ];

                $actions[] = [
                    'label' => \mh_lng('UI_BUTTON_CREATE_AUTOMATION', 'Create Automation'),
                    'attrs' => [
                        'command' => 'show-modal',
                        'commandfor' => 'config-modal',
                        'data-title' => \mh_lng('UI_BUTTON_CREATE_AUTOMATION', 'Create Automation'),
                        'data-size' => '5xl',
                        'data-dismissible' => 'false',
                        'hx-get' => \Components\Router::url('newsletter_audience_selection_modal', [
                            'partial' => 1,
                            'template_id' => $tpl['filepath'],
                            'page_mode' => 'automation',
                            'skip_template' => 1
                        ]),
                        'hx-target' => '#config-modal-body',
                        'hx-swap' => 'innerHTML',
                        'hx-push-url' => 'false',
                    ],
                    'icon' => Base::SVG_ADD,
                ];
            }

            $previewUrl = \Components\Legacy\LegacyRouter::url('preview', [
                'module' => 'mb_newsletter',
                'maintemplate_id' => 'MAIN',
                'content_module_id' => $tpl['filepath']
            ]);
            $previewUrlLngBase = $previewUrl . (strpos($previewUrl, '?') !== false ? '&lng_id=' : '?lng_id=');

            $actions[] = [
                'key' => 'preview',
                'label' => \mh_lng('MAILBEEZ_BUTTON_PREVIEW_LABEL', 'Preview'),
                'attrs' => [
                    'command' => 'show-modal',
                    'commandfor' => 'email-preview',
                    'data-title' => \mh_lng('MAILBEEZ_BUTTON_PREVIEW_LABEL', 'Preview'),
                    'data-url' => $previewUrlLngBase . $lngId . '&lock_lng=0',
                    ':data-url' => "typeof activeLngId !== 'undefined' ? '" . $previewUrlLngBase . "' + activeLngId + '&lock_lng=0' : '" . $previewUrlLngBase . $lngId . "&lock_lng=0'",
                    'data-size' => '5xl',
                    'data-width' => 'var(--container-5xl)',
                    'data-height' => '95vh',
                    'hx-target' => '#email-preview-body',
                    'hx-swap' => 'innerHTML',
                ],
                'icon' => Base::SVG_EMAIL_PREVIEW,
            ];
        }

        if ($context === 'module' && !empty($tpl['content_module_id'])) {
            $previewUrl = LegacyRouter::url('preview', [
                'module' => $tpl['module'] ?? $module,
                'maintemplate_id' => $tpl['maintemplate_id'] ?? 'MAIN',
                'content_module_id' => $tpl['content_module_id']
            ]);
            $previewUrlLngBase = $previewUrl . (strpos($previewUrl, '?') !== false ? '&lng_id=' : '?lng_id=');

            $actions[] = [
                'key' => 'preview',
                'label' => \mh_lng('MAILBEEZ_BUTTON_PREVIEW_LABEL', 'Preview'),
                'attrs' => [
                    'command' => 'show-modal',
                    'commandfor' => 'email-preview',
                    'data-title' => \mh_lng('MAILBEEZ_BUTTON_PREVIEW_LABEL', 'Preview'),
                    'data-url' => $previewUrlLngBase . $lngId . '&lock_lng=0',
                    ':data-url' => "typeof activeLngId !== 'undefined' ? '" . $previewUrlLngBase . "' + activeLngId + '&lock_lng=0' + (typeof activeGnd !== 'undefined' ? '&gnd=' + activeGnd : '') : '" . $previewUrlLngBase . $lngId . "&lock_lng=0'",
                    'data-size' => '5xl',
                    'data-width' => 'var(--container-5xl)',
                    'data-height' => '95vh',
                    'hx-target' => '#email-preview-body',
                    'hx-swap' => 'innerHTML',
                ],
                'icon' => Base::SVG_EMAIL_PREVIEW,
            ];
        }

        if ($context === 'main' && !empty($tpl['maintemplate_id'])) {
            if (!$isCurrent && !$isModal && $type === 'user' && $tpl['maintemplate_id'] !== 'MAIN') {
                $usageUrl = \Components\Router::url('template_usage', [
                    'maintemplate_id' => $tpl['maintemplate_id'],
                    'title' => $tpl['title'] ?? $tpl['maintemplate_id']
                ]);

                $actions[] = [
                    'label' => \mh_lng('UI_BUTTON_SHOW_USAGE', 'Show Usage'),
                    'attrs' => [
                        'command' => 'show-sitepanel',
                        'commandfor' => 'app-site-panel',
                        'data-tab' => 'view',
                        'hx-get' => $usageUrl,
                        'hx-target' => '#app-site-panel-body-view',
                        'hx-swap' => 'innerHTML',
                        'data-no-global-loader' => 'true',
                    ],
                    'icon' => Base::SVG_INFORMATION_CIRCLE,
                    'end_icon' => Base::SVG_SIDEBAR_RIGHT_EXPAND,
                ];
            }

            $previewUrl = LegacyRouter::url('preview', [
                'module' => 'MAIN',
                'maintemplate_id' => $tpl['maintemplate_id'],
            ]);
            $previewUrlLngBase = $previewUrl . (strpos($previewUrl, '?') !== false ? '&lng_id=' : '?lng_id=');

            $actions[] = [
                'key' => 'preview',
                'label' => \mh_lng('MAILBEEZ_BUTTON_PREVIEW_LABEL', 'Preview'),
                'attrs' => [
                    'command' => 'show-modal',
                    'commandfor' => 'email-preview',
                    'data-title' => \mh_lng('MAILBEEZ_BUTTON_PREVIEW_LABEL', 'Preview'),
                    'data-url' => $previewUrlLngBase . $lngId . '&lock_lng=0',
                    ':data-url' => "typeof activeLngId !== 'undefined' ? '" . $previewUrlLngBase . "' + activeLngId + '&lock_lng=0' + (typeof activeGnd !== 'undefined' ? '&gnd=' + activeGnd : '') : '" . $previewUrlLngBase . $lngId . "&lock_lng=0'",
                    'data-size' => '5xl',
                    'data-width' => 'var(--container-5xl)',
                    'data-height' => '95vh',
                    'hx-target' => '#email-preview-body',
                    'hx-swap' => 'innerHTML',
                ],
                'icon' => Base::SVG_EMAIL_PREVIEW,
            ];

            if (!$isCurrent && $type === 'gallery' && !$isMainGallerySelectionCard) {
                if ($isModal) {
                    $actions[] = [
                        'label' => $importLabel,
                        'attrs' => [
                            'command' => 'show-modal',
                            'commandfor' => 'confirm-modal',
                            'data-title' => $importLabel,
                            'data-type' => 'warning',
                            'hx-get' => \Components\Router::url('template_action_confirm', [
                                'confirm_action' => 'import',
                                'template_id' => $templateId,
                                'maintemplate_id' => $maintemplate_id_short,
                                'lng_id' => $lngId,
                                'newsletter_id' => $newsletterId,
                                'flow_id' => $flowId,
                                'context' => $context,
                                'module' => $module,
                                'content_module_id' => $content_module_id,
                                'partial' => 1
                            ]),
                            'hx-target' => '#confirm-modal-body',
                            'hx-swap' => 'innerHTML',
                        ],
                        'icon' => Base::SVG_ARROW_DOWN_SQUARE,
                    ];
                } else {
                    $actions[] = [
                        'label' => \mh_lng('UI_BUTTON_CREATE_DESIGN', 'Create Design'),
                        'attrs' => [
                            'command' => 'show-modal',
                            'commandfor' => 'config-modal',
                            'data-title' => \mh_lng('UI_BUTTON_CREATE_DESIGN', 'Create Design'),
                            'data-size' => '4xl',
                            'hx-get' => \Components\Router::url('template_action_confirm', [
                                'confirm_action' => 'create_from_gallery',
                                'template_id' => $templateId,
                                'lng_id' => $lngId,
                                'context' => $context,
                                'module' => $module,
                                'content_module_id' => $content_module_id,
                                'partial' => 1
                            ]),
                            'hx-target' => '#config-modal-body',
                            'hx-swap' => 'innerHTML',
                        ],
                        'icon' => Base::SVG_PLUS,
                    ];
                }
            }

            if (!$isCurrent && $type === 'basic' && $context === 'module') {
                $actions[] = [
                    'label' => \mh_lng('UI_BUTTON_CREATE_DESIGN', 'Create Design'),
                    'attrs' => [
                        'command' => 'show-modal',
                        'commandfor' => 'confirm-modal',
                        'data-title' => \mh_lng('UI_BUTTON_CREATE_DESIGN', 'Create Design'),
                        'hx-get' => \Components\Router::url('template_action_confirm', [
                            'confirm_action' => 'create_from_gallery',
                            'template_id' => $templateId,
                            'lng_id' => $lngId,
                            'context' => $context,
                            'module' => $module,
                            'content_module_id' => $content_module_id,
                            'partial' => 1
                        ]),
                        'hx-target' => '#confirm-modal-body',
                        'hx-swap' => 'innerHTML',
                    ],
                    'icon' => Base::SVG_PLUS,
                ];
            }
        }

        if (!$isCurrent && $type === 'user') {
            if ($context === 'module' && !empty($tpl['content_module_id'])) {
                if (!$isModal) {
                    if (\mh_beezui() && \mh_cfg('MH_BEEZUI_EDITOR')) {
                        $editUrl = \Components\Router::url('email_editor', [
                            'context' => 'module',
                            'module' => $tpl['module'] ?? $module,
                            'content_module_id' => $tpl['content_module_id'],
                            'lng_id' => $lngId,
                            'partial' => 1,
                            'scroll_hints' => 'false',
                        ]);
                        // Use standard editor dialog config
                        $editorDialog = \mailbeez_pro::getEditorDialog($editUrl, \mh_lng('UI_BUTTON_EDIT', 'Edit'));
                        $actions[] = [
                            'label' => $editorDialog['label'],
                            'attrs' => [
                                'command' => 'show-modal',
                                'commandfor' => $editorDialog['modal_id'],
                                'data-title' => $editorDialog['title'],
                                'data-size' => $editorDialog['size'],
                                'data-body-class' => $editorDialog['body_class'] ?? '',
                                'data-scroll-hints' => ($editorDialog['scroll_hints'] ?? true) ? 'true' : 'false',
                                'hx-get' => $editorDialog['url'],
                                'hx-target' => '#' . $editorDialog['modal_id'] . '-body',
                                'hx-swap' => 'innerHTML',
                            ],
                            'icon' => $editorDialog['icon'],
                        ];
                    }
                }
            }

            if ($context === 'main' && !empty($tpl['maintemplate_id'])) {
                if (!$isModal) {
                    if (\mh_beezui() && \mh_cfg('MH_BEEZUI_EDITOR')) {
                        $editUrl = \Components\Router::url('email_editor', [
                            'context' => 'main',
                            'maintemplate_id' => $tpl['maintemplate_id'],
                            'lng_id' => $lngId,
                            'partial' => 1,
                            'scroll_hints' => 'false',
                        ]);
                        // Use standard editor dialog config
                        $editorDialog = \mailbeez_pro::getEditorDialog($editUrl, \mh_lng('UI_BUTTON_EDIT', 'Edit'));
                        $actions[] = [
                            'label' => $editorDialog['label'],
                            'attrs' => [
                                'command' => 'show-modal',
                                'commandfor' => $editorDialog['modal_id'],
                                'data-title' => $editorDialog['title'],
                                'data-size' => $editorDialog['size'],
                                'data-body-class' => $editorDialog['body_class'] ?? '',
                                'data-scroll-hints' => ($editorDialog['scroll_hints'] ?? true) ? 'true' : 'false',
                                'hx-get' => $editorDialog['url'],
                                'hx-target' => '#' . $editorDialog['modal_id'] . '-body',
                                'hx-swap' => 'innerHTML',
                            ],
                            'icon' => $editorDialog['icon'],
                        ];
                    } else {
                        $editUrl = LegacyRouter::url('mainEditor', ['maintemplate_id' => $tpl['maintemplate_id']]);
                        $actions[] = [
                            'label' => \mh_lng('UI_BUTTON_EDIT', 'Edit'),
                            'href' => $editUrl,
                            'icon' => Base::SVG_EDIT,
                        ];
                    }
                }

                if (!($tpl['is_main'] ?? false) || ($maintemplate_id_short !== null && $maintemplate_id_short !== 'MAIN')) {
                    $actions[] = [
                        'label' => $importLabel,
                        'attrs' => [
                            'command' => 'show-modal',
                            'commandfor' => 'confirm-modal',
                            'data-title' => $importLabel,
                            'data-type' => 'warning',
                            'hx-get' => \Components\Router::url('template_action_confirm', [
                                'confirm_action' => 'import',
                                'template_id' => $templateId,
                                'maintemplate_id' => $maintemplate_id_short,
                                'lng_id' => $lngId,
                                'newsletter_id' => $newsletterId,
                                'flow_id' => $flowId,
                                'context' => $context,
                                'module' => $module,
                                'content_module_id' => $content_module_id,
                                'partial' => 1
                            ]),
                            'hx-target' => '#confirm-modal-body',
                            'hx-swap' => 'innerHTML',
                        ],
                        'icon' => Base::SVG_ARROW_DOWN_SQUARE,
                    ];
                }
            }

            if (!$isModal && !empty($tpl['url_export'])) {
                $actions[] = [
                    'label' => \mh_lng('UI_BUTTON_TEMPLATE_EXPORT', 'Export'),
                    'href' => $tpl['url_export'],
                    'icon' => '<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-5"><path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5m-13.5-9L12 3m0 0 4.5 4.5M12 3v13.5" /></svg>',
                ];
            }
            if (!$isModal) {
                $actions[] = ['divider' => true];
            }
            if (!$isModal && !empty($tpl['url_delete'])) {
                $usageCount = 0;
                if (array_key_exists('usage_count', $tpl)) {
                    // Usage count precomputed in a single DB scan by the caller
                    // (see pages/editor_templates.php) to avoid a costly per-card
                    // get_template_usage() call (full-table scan + heavy
                    // resolve_usage_key() model/module instantiation).
                    $usageCount = (int)$tpl['usage_count'];
                } elseif (!empty($templateId)) {
                    if (!class_exists('template_manager')) {
                        include_once(MH_DIR_CONFIG . 'config_editor/classes/template_manager.php');
                    }
                    if (class_exists('template_manager')) {
                        $usageCount = count(\template_manager::get_template_usage($templateId));
                    }
                }

                if ($usageCount > 0) {
                    $actions[] = [
                        'label' => \mh_lng('UI_BUTTON_DELETE', 'Delete'),
                        'attrs' => [
                            'onclick' => "alert('" . \addslashes(\mh_lng('UI_ERROR_TEMPLATE_IN_USE', 'This template is in use and cannot be deleted.')) . "')",
                            'class' => 'text-red-600 opacity-50',
                        ],
                        'icon' => Base::SVG_TRASH,
                    ];
                } else {
                    $actions[] = [
                        'label' => \mh_lng('UI_BUTTON_DELETE', 'Delete'),
                        'attrs' => [
                            'command' => 'show-modal',
                            'commandfor' => 'confirm-modal',
                            'data-title' => \mh_lng('UI_BUTTON_DELETE', 'Delete'),
                            'data-type' => 'alert',
                            'hx-get' => \Components\Router::url('template_action_confirm', [
                                'confirm_action' => 'delete',
                                'template_id' => $templateId,
                                'lng_id' => $lngId,
                                'newsletter_id' => $newsletterId,
                                'flow_id' => $flowId,
                                'context' => $context,
                                'module' => $module,
                                'content_module_id' => $content_module_id,
                                'partial' => 1
                            ]),
                            'hx-target' => '#confirm-modal-body',
                            'hx-swap' => 'innerHTML',
                            'class' => 'text-red-600',
                        ],
                        'icon' => Base::SVG_TRASH,
                    ];
                }
            }
        }

        if (!empty($onlyActions)) {
            $allowedActionKeys = [];
            foreach ($onlyActions as $actionKey) {
                $allowedActionKeys[(string)$actionKey] = true;
            }

            $actions = array_values(array_filter($actions, static function ($item) use ($allowedActionKeys) {
                if (!is_array($item)) {
                    return false;
                }
                $key = isset($item['key']) ? (string)$item['key'] : '';
                return $key !== '' && isset($allowedActionKeys[$key]);
            }));
        }

        $previewId = $type . $idx . '_' . substr(md5(uniqid()), 0, 8);

        // Preview content
        ob_start();
        ?>
        <?php if (!empty($tpl['hasThumbnail'])): ?>
            <img src="<?=  \Components\Router::normalizeUrl((string)$tpl['hasThumbnail'])  ?>" width="300" height="400"
                 class="w-full h-auto block opacity-0 transition-opacity duration-500 will-change-transform"
                 loading="lazy" decoding="async"
                 onload="this.classList.remove('opacity-0')"
                 @load="recalc()"
            >
        <?php else: ?>
            <div class="flex items-center justify-center h-full text-gray-300 placeholder-content animate-pulse">
                <div class="size-24  [&_svg]:size-full"><?= Base::SVG_MAIL ?></div>
            </div>
        <?php endif; ?>

        <?php if (!empty($tpl['generate_thumbnail_url'])): ?>
            <div class="generating-indicator absolute inset-0 flex flex-col items-center justify-center bg-gray-100/60 dark:bg-gray-900/60 opacity-0 transition-opacity duration-300 pointer-events-none text-secondary">
                <?= Base::SVG_SPINNER ?>
            </div>
        <?php endif; ?>
        <?php
        $previewContent = ob_get_clean();

        // Language flags
        $supportedLanguages = $tpl['supported_languages'] ?? [];
        $languagesHtml = '';
        if (!empty($supportedLanguages) && is_array($supportedLanguages)) {
            $sessionLngId = (int) \mh_session('languages_id', 1);
            $sessionLngCode = function_exists('mh_get_language_code') ? \mh_get_language_code($sessionLngId) : '';
            $sessionLngName = \mh_session('language', '');

            // Reorder: session language first
            usort($supportedLanguages, function ($a, $b) use ($sessionLngCode, $sessionLngName) {
                $isA = ($sessionLngCode && $a === $sessionLngCode) || ($sessionLngName && strcasecmp($a, $sessionLngName) === 0);
                $isB = ($sessionLngCode && $b === $sessionLngCode) || ($sessionLngName && strcasecmp($b, $sessionLngName) === 0);
                if ($isA && !$isB) return -1;
                if (!$isA && $isB) return 1;
                return 0;
            });

            $count = count($supportedLanguages);
            if ($count <= 5) {
                $display = $supportedLanguages;
                $more = 0;
            } else {
                $display = array_slice($supportedLanguages, 0, 3);
                $more = $count - 3;
            }

            $languagesTriggerContentHtml = '';
            foreach ($display as $i => $lang) {
                $zIndex = ($i + 1) * 10;
                $flag = \Components\Form\BaseField::flagIconHtml($lang, " z-{$zIndex} inline-block size-4! rounded-full ring-1 ring-white outline -outline-offset-1 outline-black/5 shadow-md", "circle");
                if ($flag) {
                    $languagesTriggerContentHtml .= $flag;
                }
            }
            if ($more > 0) {
                $languagesTriggerContentHtml .= '<span class="ml-3 z-40 inline-flex items-center justify-center size-4  text-[11px] font-medium text-secondary  shrink-0">+' . $more . '</span>';
            }

            // Tooltip content: all languages with icons and names
            $allLanguages = \mh_get_languages();
            $langNames = [];
            foreach ($allLanguages as $l) {
                $langNames[$l['code']] = $l['name'];
            }

            $tooltipContentHtml = '<div class="flex flex-col gap-3 p-3 text-xs">';
            foreach ($supportedLanguages as $langCode) {
                $flag = \Components\Form\BaseField::flagIconHtml($langCode, "inline-block size-4! rounded-full ring-1 ring-white/50", "circle");
                $name = $langNames[$langCode] ?? $langCode;
                $tooltipContentHtml .= '<div class="flex items-center gap-3">';
                $tooltipContentHtml .= $flag;
                $tooltipContentHtml .= '<span class="whitespace-nowrap">' . Base::h($name) . '</span>';
                $tooltipContentHtml .= '</div>';
            }
            $tooltipContentHtml .= '</div>';

            $languagesHtml = Tooltip::render($languagesTriggerContentHtml, $tooltipContentHtml, [
                'anchor' => 'top start',
                'popover_class' => 'min-w-[120px]',
                'trigger_attrs' => [
                    'class' => 'group-[.is-small]:hidden flex items-center -space-x-1.5 overflow-hidden shrink-0 ml-2 p-0.5 opacity-70 hover:opacity-100 bg-transparent border-0 p-0'
                ]
            ]);
        }

        // Body Header
        ob_start();
        ?>
        <h4 class="text-sm font-semibold text-primary truncate flex items-center gap-1" title="<?= Base::h(Base::lng($tpl['title'] ?? '', $tpl['title'] ?? '')) ?>">
            <span class="truncate"><?= Base::h(Base::lng($tpl['title'] ?? '', $tpl['title'] ?? '')) ?></span>
            <?php if ($tpl['is_main'] ?? false): ?>
                <span class="inline-flex items-center rounded-md bg-brand/10 px-1.5 py-0.5 text-[10px] font-medium text-brand ring-1 ring-inset ring-brand/20 uppercase shrink-0">main</span>
            <?php endif; ?>
            <?php if ($tpl['is_current'] ?? false): ?>
                <span class="inline-flex items-center rounded-md bg-orange-500/10 px-1.5 py-0.5 text-[10px] font-medium text-orange-600 ring-1 ring-inset ring-orange-500/20 uppercase shrink-0 gap-1">
                    <?= \mh_lng('UI_TEXT_STATUS_CURRENT', 'current') ?>
                </span>
            <?php endif; ?>
            <?= $languagesHtml ?>
        </h4>
        <?php
        $bodyHeaderHtml = ob_get_clean();

        // Body Footer
        ob_start();
        ?>
        <p class="text-[10px] text-secondary mt-0.5 uppercase tracking-wider font-medium flex flex-wrap items-center">
            <span class="flex-shrink-0"><?= Base::h($type) ?></span>
            <?php if ($context === 'module' && !empty($tpl['module'])): ?>
                <span class="mx-1 opacity-50 group-[.is-small]:hidden">&middot;</span>
                <span class="normal-case tracking-normal font-normal truncate max-w-[150px]" title="<?= Base::h($tpl['module']) ?>">
                    <?= Base::h(\Components\ModuleLoader::title($tpl['module']) ?: $tpl['module']) ?>
                </span>
            <?php endif; ?>
            <?php if ($type === 'user'): ?>
                <?php
                $date = !empty($tpl['last_modified']) && $tpl['last_modified'] !== '0000-00-00 00:00:00' ? $tpl['last_modified'] : ($tpl['date_added'] ?? '');
                if ($date && $date !== '0000-00-00 00:00:00'): ?>
                    <span class="mx-1 opacity-50 group-[.is-small]:hidden">&middot;</span>
                    <span class="normal-case tracking-normal font-normal group-[.is-small]:w-full" x-data="{ date: new Date('<?= date('Y-m-d\TH:i:s', strtotime($date)) ?>') }" x-timeago="date"><?= Base::h(\mh_datetime_short($date)) ?></span>
                <?php endif; ?>
            <?php endif; ?>
        </p>
        <?php
        $bodyFooterHtml = ob_get_clean();

        $triggerBtnHtml = \Components\Button::render('', [
                'variant' => 'ghost',
                'size' => 'md',
                'icon' => \Components\Base::SVG_ELLIPSIS_HORIZONTAL,
                'attrs' => [ '@click.stop' => '', 'aria-label' => \mh_lng('UI_MORE', 'More') ],
        ]);

        $actionsWrapperAttrs = ($isNewsletterSelectionCard || $isMainGallerySelectionCard) ? ['data-skip-template-card-click' => '1'] : [];
        $actionsHtml = Dropdown::render([
            'wrapper_attrs' => $actionsWrapperAttrs,
            'trigger_tag' => 'div',
            'trigger_html' => $triggerBtnHtml,
            'trigger_attrs' => [ '@click.stop' => '' ],
            'items' => $actions,
            'anchor' => 'bottom end'
        ]);

        $primaryActionHtml = '';
        $cardAttrs = '';
        $cardClasses = '';
        if ($isNewsletterSelectionCard || $isMainGallerySelectionCard) {
            $cardClasses = SelectableCard::cardClasses($isNewsletterSelectionCard && $isNewsletterPreselected);

            $primaryActionAttrs = $isNewsletterSelectionCard ? $newsletterPrimaryActionAttrs : $mainGalleryPrimaryActionAttrs;
            $primaryActionHtml = '<button ' . Base::attrs(array_merge($primaryActionAttrs, [
                'type' => 'button',
                'class' => 'hidden',
                'tabindex' => '-1',
                'aria-hidden' => 'true',
                'data-card-primary-action' => '1',
                'data-skip-template-card-click' => '1',
            ])) . '></button>';

            if ($isNewsletterSelectionCard) {
                $selectionOptionsJs = "{ containerSelector: '#editor-templates-container', cardSelector: '[data-newsletter-template-card=\"1\"]', skipSelector: '[data-skip-template-card-click]', onSelect: function(card) { var u = card.getAttribute('data-select-url') || ''; window.dispatchEvent(new CustomEvent('newsletter-template-selected', { detail: { select_url: u, template_id: card.getAttribute('data-template-id') || '' } })); } }";

                $cardAttrs = Base::attrs([
                    'data-newsletter-template-card' => '1',
                    'data-select-url' => $selectUrl,
                    'data-template-id' => (string)($tpl['filepath'] ?? ''),
                    'aria-selected' => $isNewsletterPreselected ? 'true' : 'false',
                    '@click' => "if (window.__mhSelectableCard) { window.__mhSelectableCard.handleClick(\$event, \$el, $selectionOptionsJs); }",
                    '@dblclick' => "if (window.__mhSelectableCard) { window.__mhSelectableCard.handleDoubleClick(\$event, \$el, $selectionOptionsJs); }",
                ]);
            } else {
                $selectionOptionsJs = "{ containerSelector: '#editor-templates-container', cardSelector: '[data-main-gallery-template-card=\"1\"]', skipSelector: '[data-skip-template-card-click]', onSelect: function(card) { var u = card.getAttribute('data-select-url') || ''; window.dispatchEvent(new CustomEvent('main-gallery-template-selected', { detail: { select_url: u, template_id: card.getAttribute('data-template-id') || '' } })); } }";

                $cardAttrs = Base::attrs([
                    'data-main-gallery-template-card' => '1',
                    'data-select-url' => (string)($mainGalleryPrimaryActionAttrs['hx-get'] ?? ''),
                    'data-template-id' => (string)($tpl['filepath'] ?? ''),
                    'aria-selected' => 'false',
                    '@click' => "if (window.__mhSelectableCard) { window.__mhSelectableCard.selectCard(\$el, $selectionOptionsJs); }",
                    '@dblclick' => "if (window.__mhSelectableCard) { window.__mhSelectableCard.handleDoubleClick(\$event, \$el, $selectionOptionsJs); }",
                ]);
            }
        }

        $extraScripts = '';
        if (empty($tpl['hasThumbnail']) && !empty($tpl['generate_thumbnail_url'])) {
            ob_start();
            ?>
            <script>
                (function() {
                    if (typeof updateThumbnail === 'function') {
                        updateThumbnail('<?= $previewId ?>', '<?= $tpl['maintemplate_id'] ?>', '<?= $tpl['content_module_id'] ?>', '<?= $tpl['generate_thumbnail_url'] ?>');
                    }
                })();
            </script>
            <?php
            $extraScripts = ob_get_clean();
        }

        $html = TemplateCardUI::render([
            'card_classes' => $cardClasses,
            'card_attrs' => $cardAttrs,
            'preview_classes' => 'emailthumbnail',
            'preview_attrs' => Base::attrs([
                'id' => 'preview_' . $previewId,
                'x-data' => "templatePreviewScroller",
                '@mouseenter' => "start()",
                '@mouseleave' => "stop(true)",
                '@preview-img-loaded' => "recalc()",
                'data-preview-id' => $previewId,
                'data-maintemplate-id' => $tpl['maintemplate_id'] ?? '',
                'data-content-module-id' => $tpl['content_module_id'] ?? '',
                'data-generate-url' => $tpl['generate_thumbnail_url'] ?? '',
            ]),
            'preview_content' => $previewContent,
            'body_header_html' => $bodyHeaderHtml,
            'body_footer_html' => $bodyFooterHtml,
            'actions_html' => $actionsHtml,
            'scripts' => $primaryActionHtml . $extraScripts
        ]);

        return $scripts . $html;
    }
}
