<?php
namespace Components\Resources;

use Components\Base;
use Components\Dropdown;
use Components\Legacy\LegacyRouter;
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() {
                // Clear the current queue to ensure we follow the DOM order of the found targets
                thumbnailQueue = [];

                var targets = document.querySelectorAll('.emailthumbnail[data-generate-url]');
                targets.forEach(function(target) {
                    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);
        $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 = '';
        if (!self::$scriptsRendered

//                && !$tpl['hasThumbnail'] && !empty($tpl['generate_thumbnail_url'])

        ) {
            $thumbnail_update_ajax_url = LegacyRouter::url('thumbnailUpdate', ['lng_id' => $lngId]);
            $scripts = self::renderScripts($thumbnail_update_ajax_url);
        }

        $selectUrl = $tpl['url_select'] ?? '';
        
        $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;
            }
        }

        if (!$isCurrent && $isModal && $context === 'module' && !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',
                                    'select_url' => $selectUrl,
                                    'content_module_id' => $content_module_id,
                                    'partial' => 1
                            ]),
                            'data-type' => 'warning',
                            'hx-target' => '#confirm-modal-body',
                            'hx-swap' => 'innerHTML',
                    ],
                    'icon' => Base::SVG_PLAY,
            ];
        }

        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[] = [
                '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_DEVICE_MOBILE,
            ];
        }

        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-modal',
                        'commandfor' => 'editor-inline-modal',
                        'data-title' => \mh_lng('UI_BUTTON_SHOW_USAGE', 'Show Usage'),
                        'data-size' => '2xl',
                        'hx-get' => $usageUrl,
                        'hx-target' => '#editor-inline-modal-body',
                        'hx-swap' => 'innerHTML',
                    ],
                    'icon' => Base::SVG_INFORMATION_CIRCLE,
                ];
            }

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

            $actions[] = [
                '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_DEVICE_MOBILE,
            ];

            if (!$isCurrent && $type === 'gallery') {
                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' => '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 === '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,
                        ]);
                        // 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'] ?? '',
                                '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,
                        ]);
                        // 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'] ?? '',
                                '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 (!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,
                    ];
                }
            }
        }

        $previewId = $type . $idx;

        // Preview content
        ob_start();
        ?>
        <?php if ($tpl['hasThumbnail']): ?>
            <img src="<?= $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-12  [&_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-sm">';
            foreach ($supportedLanguages as $langCode) {
                $flag = \Components\Form\BaseField::flagIconHtml($langCode, "inline-block size-5! rounded-full ring-1 ring-white/20", "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') ],
        ]);

        $actionsHtml = Dropdown::render([
            'wrapper_attrs' => [],
            'trigger_tag' => 'div',
            'trigger_html' => $triggerBtnHtml,
            'trigger_attrs' => [ '@click.stop' => '' ],
            'items' => $actions,
            'anchor' => 'bottom end'
        ]);

        $extraScripts = '';
        if (!$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([
            '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' => $extraScripts
        ]);

        return $scripts . $html;
    }
}
