/**
 * TamRank Content Tab - Content Analysis JavaScript
 *
 * Handles content extraction from various editors (Gutenberg, Classic, Divi, Elementor)
 * and triggers real-time content analysis via AJAX.
 */
(function ($) {
    'use strict';

    /**
     * Fill one placeholder without letting the value expand.
     *
     * Copy of the canonical helper in assets/js/tamrank-onboarding.js; read the
     * docblock there for why String.replace() with a STRING replacement mangles
     * any value carrying $&, $`, $' or $$, and why this is a copy instead of a
     * shared global. `token` may be a string or a RegExp; a FUNCTION replacement
     * is exempt from that expansion in both cases. Keep the body identical.
     */
    function fillPlaceholder(tpl, token, value) {
        var literal = String(value);
        return String(tpl).replace(token, function () { return literal; });
    }

    // Content Tab Controller
    const TamRankContentTab = {

        // Configuration
        config: {
            debounceDelay: 1500,
            ajaxAction: 'tamrank_analyze_content',
            selectors: {
                tab: '.tam-meta-tab[data-tab="content"]',
                tabContent: '#tam-tab-content',
                contentTab: '#tam-content-tab',
                reanalyzeBtn: '#content-reanalyze-btn',
                loadingOverlay: '#content-loading',
                scoreBadge: '#content-score-badge',
                scoreValue: '#content-score-value',
                scoreLabel: '#content-score-label',
                scoreBar: '#content-score-bar',
                issuesList: '#content-issues-list',
                checksCount: '#content-checks-count',
                allChecks: '#content-all-checks',
                analysisDetails: '#content-analysis-details',
                improvementsCount: '#content-improvements-count',
                criticalsCount: '#content-criticals-count'
            }
        },

        // State
        state: {
            initialized: false,
            isAnalyzing: false,
            lastContent: '',
            lastKeyword: '',
            debounceTimer: null
        },

        /**
         * Initialize the Content Tab
         */
        init: function () {
            // Guard against double-init. On Gutenberg both $(document).ready and
            // wp.domReady fire (see boot code at the bottom of this file), which
            // would otherwise bind every delegated handler twice. For toggle-based
            // handlers like the accordions that means each click flips is-open twice
            // and cancels out, so the panels never open.
            if (this.state.initialized) {
                return;
            }
            this.state.initialized = true;
            this.bindEvents();
            this.initAccordions();
        },

        /**
         * Bind all event handlers
         */
        bindEvents: function () {
            const self = this;

            // Reanalyze button. This is the one call site that asks the server to
            // skip the five-minute brake on the page fetch: pressing the button is
            // an explicit request for a fresh measurement. Every other call site
            // below fires on its own (a typing pause, a tab click, a builder
            // event) and must keep doing zero fetches.
            $(document).on('click', this.config.selectors.reanalyzeBtn, function (e) {
                e.preventDefault();
                self.triggerAnalysis(true);
            });

            // Content changes - Gutenberg
            if (this.isGutenberg()) {
                this.bindGutenbergEvents();
            }

            // Content changes - Classic Editor
            this.bindClassicEditorEvents();

            // Content changes - Divi
            this.bindDiviEvents();

            // Content changes - Elementor
            this.bindElementorEvents();

            // Focus keyword changes
            $(document).on('input', '#_tam_rank_focus_keyword', this.debounce(function () {
                if ($(self.config.selectors.tabContent).is(':visible')) {
                    self.triggerAnalysis();
                }
            }, this.config.debounceDelay));

            // Tab click - refresh analysis
            $(document).on('click', this.config.selectors.tab, function () {
                // Small delay to ensure tab is visible
                setTimeout(() => {
                    if (!self.state.isAnalyzing) {
                        self.triggerAnalysis();
                    }
                }, 100);
            });
        },

        /**
         * Initialize accordion functionality
         */
        initAccordions: function () {
            $(document).on('click', '.tam-content-accordion-header', function (e) {
                e.preventDefault();
                const $header = $(this);
                const targetId = $header.data('target');
                const $content = $('#' + targetId);
                const $accordion = $header.closest('.tam-content-accordion');
                const $chevron = $header.find('svg:last-child');

                $accordion.toggleClass('is-open');

                if ($accordion.hasClass('is-open')) {
                    $content.slideDown(200);
                    $chevron.css('transform', 'rotate(180deg)');
                } else {
                    $content.slideUp(200);
                    $chevron.css('transform', 'rotate(0deg)');
                }
            });

            // Recommendation cards expand to reveal their "How to fix this?" tip.
            // The chevron rotation is CSS-driven off `is-open`, but the tip must be
            // slid open explicitly: the JS-rebuilt cards carry an inline display:none
            // that a CSS `.is-open` rule cannot override, so toggling the class alone
            // would leave the tip hidden.
            $(document).on('click', '.tam-content-recommendation-header', function (e) {
                e.preventDefault();
                var $rec = $(this).closest('.tam-content-recommendation');
                var $tip = $rec.find('.tam-content-recommendation-tip');
                $rec.toggleClass('is-open');
                if ($rec.hasClass('is-open')) {
                    $tip.stop(true, true).slideDown(200);
                } else {
                    $tip.stop(true, true).slideUp(200);
                }
            });
        },

        /**
         * Check if Gutenberg editor is active
         */
        isGutenberg: function () {
            return typeof wp !== 'undefined' &&
                typeof wp.data !== 'undefined' &&
                typeof wp.data.select !== 'undefined' &&
                wp.data.select('core/editor');
        },

        /**
         * Bind Gutenberg editor events
         */
        bindGutenbergEvents: function () {
            const self = this;

            // Subscribe to content changes
            if (wp.data && wp.data.subscribe) {
                let previousContent = '';

                wp.data.subscribe(this.debounce(function () {
                    if (!$(self.config.selectors.tabContent).is(':visible')) {
                        return;
                    }
                    const content = self.getGutenbergContent();
                    if (content !== previousContent) {
                        previousContent = content;
                        self.triggerAnalysis();
                    }
                }, this.config.debounceDelay));
            }
        },

        /**
         * Bind Classic Editor (TinyMCE) events
         */
        bindClassicEditorEvents: function () {
            const self = this;

            // Wait for TinyMCE to be ready
            $(document).on('tinymce-editor-init', function (event, editor) {
                if (editor.id === 'content') {
                    editor.on('input change keyup', self.debounce(function () {
                        if ($(self.config.selectors.tabContent).is(':visible')) {
                            self.triggerAnalysis();
                        }
                    }, self.config.debounceDelay));
                }
            });

            // Also bind to text mode
            $(document).on('input', '#content', this.debounce(function () {
                if ($(self.config.selectors.tabContent).is(':visible')) {
                    self.triggerAnalysis();
                }
            }, this.config.debounceDelay));
        },

        /**
         * Bind Divi Builder events
         */
        bindDiviEvents: function () {
            const self = this;

            // Divi uses a custom event system
            $(window).on('et_fb_section_content_change', this.debounce(function () {
                if ($(self.config.selectors.tabContent).is(':visible')) {
                    self.triggerAnalysis();
                }
            }, this.config.debounceDelay));

            // Also check for Divi iframe changes
            if (typeof ETBuilderBackend !== 'undefined') {
                setInterval(function () {
                    if (!$(self.config.selectors.tabContent).is(':visible')) {
                        return;
                    }
                    const content = self.getDiviContent();
                    if (content !== self.state.lastContent) {
                        self.state.lastContent = content;
                        self.triggerAnalysis();
                    }
                }, 3000);
            }
        },

        /**
         * Bind Elementor events
         */
        bindElementorEvents: function () {
            const self = this;

            // Elementor uses custom events
            if (typeof elementor !== 'undefined') {
                elementor.channels.editor.on('change', this.debounce(function () {
                    if ($(self.config.selectors.tabContent).is(':visible')) {
                        self.triggerAnalysis();
                    }
                }, this.config.debounceDelay));

                // Also on save
                elementor.channels.editor.on('saved', function () {
                    if ($(self.config.selectors.tabContent).is(':visible')) {
                        self.triggerAnalysis();
                    }
                });
            }

            // Check for Elementor preview iframe
            $(document).on('elementor:init', function () {
                if (elementor.channels && elementor.channels.editor) {
                    elementor.channels.editor.on('change', self.debounce(function () {
                        if ($(self.config.selectors.tabContent).is(':visible')) {
                            self.triggerAnalysis();
                        }
                    }, self.config.debounceDelay));
                }
            });
        },

        /**
         * Get content from Gutenberg editor
         */
        getGutenbergContent: function () {
            if (!this.isGutenberg()) return '';

            try {
                const editor = wp.data.select('core/editor');
                const blocks = editor.getBlocks();

                // Serialize blocks to HTML
                let content = '';
                blocks.forEach(function (block) {
                    content += wp.blocks.serialize(block);
                });

                return content;
            } catch (e) {
                console.warn('TamRank: Could not get Gutenberg content', e);
                return '';
            }
        },

        /**
         * Get content from Classic Editor (TinyMCE)
         */
        getClassicContent: function () {
            // Check TinyMCE first
            if (typeof tinyMCE !== 'undefined' && tinyMCE.get('content')) {
                return tinyMCE.get('content').getContent();
            }

            // Fallback to textarea
            const $textarea = $('#content');
            if ($textarea.length) {
                return $textarea.val();
            }

            return '';
        },

        /**
         * Get content from Divi Builder
         * For content analysis, we need the raw shortcodes (not rendered text)
         * so we always prefer the hidden content field that contains shortcodes
         */
        getDiviContent: function () {
            let content = '';

            // PRIORITY: Get the raw content with shortcodes from hidden fields
            // This is essential for image detection from [et_pb_image] shortcodes
            const $diviOldContent = $('#et_pb_old_content');
            if ($diviOldContent.length && $diviOldContent.val()) {
                content = $diviOldContent.val();
            }

            // Fallback to main content textarea if old_content is empty
            if (!content) {
                const $mainContent = $('#content');
                if ($mainContent.length && $mainContent.val()) {
                    content = $mainContent.val();
                }
            }

            // If still no content, try to extract from Divi's data store
            // This is useful when editing with Visual Builder
            if (!content && typeof ETBuilderBackend !== 'undefined' && ETBuilderBackend.currentPage) {
                try {
                    const modules = ETBuilderBackend.currentPage.modules || [];
                    let shortcodeContent = '';

                    modules.forEach(function (module) {
                        // Build shortcode-like content for each module
                        if (module.type === 'et_pb_image' && module.attrs && module.attrs.src) {
                            const src = module.attrs.src || '';
                            const alt = module.attrs.alt || '';
                            shortcodeContent += '[et_pb_image src="' + src + '" alt="' + alt + '"] ';
                        }
                        if (module.attrs && module.attrs.content) {
                            shortcodeContent += module.attrs.content + ' ';
                        }
                    });

                    if (shortcodeContent) {
                        content = shortcodeContent;
                    }
                } catch (e) {
                    console.warn('TamRank: Could not get Divi content from store', e);
                }
            }

            // Last resort: try to get rendered text from Divi iframe
            if (!content) {
                const $diviFrame = $('#et-fb-app-frame, #et_pb_layout iframe').first();
                if ($diviFrame.length) {
                    try {
                        const frameDoc = $diviFrame[0].contentDocument || $diviFrame[0].contentWindow.document;
                        content = $(frameDoc).find('.et_pb_module').text();
                    } catch (e) {
                        console.warn('TamRank: Could not access Divi iframe', e);
                    }
                }
            }

            return content;
        },

        /**
         * Get content from Elementor
         */
        getElementorContent: function () {
            let content = '';

            // Try to get from Elementor's data
            if (typeof elementor !== 'undefined' && elementor.elements) {
                try {
                    const self = this;
                    elementor.elements.forEach(function (element) {
                        const settings = element.get('settings');
                        if (settings) {
                            // Text widgets
                            if (settings.get('editor')) {
                                content += settings.get('editor') + ' ';
                            }
                            // Heading widgets
                            if (settings.get('title')) {
                                content += settings.get('title') + ' ';
                            }
                            // Text editor widgets
                            if (settings.get('text')) {
                                content += settings.get('text') + ' ';
                            }
                            // Image widgets - extract image IDs for detection
                            const image = settings.get('image');
                            if (image && image.id) {
                                content += '<img class="wp-image-' + image.id + '" src="' + (image.url || '') + '" /> ';
                            }
                            // Background images
                            const bgImage = settings.get('background_image');
                            if (bgImage && bgImage.id) {
                                content += '<img class="wp-image-' + bgImage.id + '" src="' + (bgImage.url || '') + '" /> ';
                            }
                        }
                    });
                } catch (e) {
                    console.warn('TamRank: Could not get Elementor content from data', e);
                }
            }

            // Try to get from Elementor preview iframe
            const $elementorFrame = $('#elementor-preview-iframe');
            if ($elementorFrame.length) {
                try {
                    const frameDoc = $elementorFrame[0].contentDocument || $elementorFrame[0].contentWindow.document;
                    // Get text content
                    content += $(frameDoc).find('.elementor-widget-container').text();
                    // Also get img tags with wp-image classes for image detection
                    $(frameDoc).find('img[class*="wp-image-"]').each(function () {
                        content += ' ' + this.outerHTML + ' ';
                    });
                } catch (e) {
                    console.warn('TamRank: Could not access Elementor iframe', e);
                }
            }

            return content;
        },

        /**
         * Get all content from active editor
         * Priority: Divi/Elementor (page builders) > Gutenberg > Classic
         * Page builders need special handling for shortcode extraction
         */
        getAllContent: function () {
            let content = '';

            // Check for Divi first - it stores content with shortcodes
            // Detect Divi by checking for ETBuilderBackend OR #et_pb_old_content field
            const isDivi = typeof ETBuilderBackend !== 'undefined' ||
                $('#et_pb_old_content').length > 0 ||
                $('body').hasClass('et-fb');

            if (isDivi) {
                const diviContent = this.getDiviContent();
                if (diviContent) {
                    content = diviContent;
                }
            }

            // Try Elementor
            if (!content && typeof elementor !== 'undefined') {
                const elementorContent = this.getElementorContent();
                if (elementorContent) content = elementorContent;
            }

            // Try Gutenberg
            if (!content && this.isGutenberg()) {
                content = this.getGutenbergContent();
            }

            // If still no content, try Classic Editor
            if (!content) {
                content = this.getClassicContent();
            }

            return content;
        },

        /**
         * Trigger content analysis
         *
         * @param {boolean} [forceFetch] Let the server skip the five-minute brake
         *                               on the page fetch. Only the Reanalyse
         *                               button passes this; the automatic
         *                               re-analyses leave it off on purpose.
         */
        triggerAnalysis: function (forceFetch) {
            const self = this;

            // Prevent multiple simultaneous analyses
            if (this.state.isAnalyzing) {
                return;
            }

            // Check if content tab is visible
            if (!$(this.config.selectors.tabContent).is(':visible')) {
                return;
            }

            const content = this.getAllContent();
            const keyword = $('#_tam_rank_focus_keyword').val() || '';
            const postId = $('#post_ID').val() || 0;

            this.state.isAnalyzing = true;

            // Show loading state
            this.showLoading();

            // Send AJAX request
            $.ajax({
                url: tamRankContent.ajaxUrl,
                type: 'POST',
                data: {
                    action: this.config.ajaxAction,
                    nonce: tamRankContent.nonce,
                    content: content,
                    focus_keyword: keyword,
                    post_id: postId,
                    force_fetch: forceFetch ? '1' : '0'
                },
                success: function (response) {
                    if (response.success) {
                        self.updateUI(response.data);
                    } else {
                        self.showError(response.data || tamRankContent.strings.analysisFailed);
                    }
                },
                error: function (xhr, status, error) {
                    console.error('TamRank Content Analysis Error:', error);
                    self.showError(tamRankContent.strings.analysisError);
                },
                complete: function () {
                    self.state.isAnalyzing = false;
                    self.hideLoading();
                }
            });
        },

        /**
         * Update the UI with analysis results
         */
        updateUI: function (data) {
            this.updateScore(data.score, data.warnings_count, data.errors_count);
            this.updateTopIssues(data.top_issues);
            this.updateCategories(data.categories, data.passed_count, data.total_checks);
            this.updateDetails(data.details);
        },

        /**
         * Update score display with SVG circle
         */
        updateScore: function (score, warningsCount, errorsCount) {
            const $scoreValue = $(this.config.selectors.scoreValue);
            const $scoreLabel = $(this.config.selectors.scoreLabel);
            const $scoreProgress = $('#content-score-progress');
            const $improvementsCount = $(this.config.selectors.improvementsCount);
            const $criticalsCount = $(this.config.selectors.criticalsCount);

            // SVG Circle calculations
            const radius = 42;
            const circumference = 2 * Math.PI * radius;
            const dashoffset = circumference - (score / 100) * circumference;
            const scoreColor = this.getScoreColor(score);
            const scoreLabel = this.getScoreLabel(score);

            // Animate score number
            $({ value: parseInt($scoreValue.text()) || 0 }).animate({ value: score }, {
                duration: 500,
                step: function (now) {
                    $scoreValue.text(Math.round(now));
                }
            });

            // Update SVG circle
            $scoreProgress.css({
                'stroke': scoreColor,
                'stroke-dashoffset': dashoffset
            });

            // Update label
            $scoreLabel.text(scoreLabel);

            // Toggle status visibility
            const hasIssues = (warningsCount > 0 || errorsCount > 0);
            if (hasIssues) {
                $('#content-status-issues').show();
                $('#content-status-all-good').hide();
                // Update counts
                $improvementsCount.text(warningsCount || 0);
                $criticalsCount.text(errorsCount || 0);
            } else {
                $('#content-status-issues').hide();
                $('#content-status-all-good').show();
            }

            // Also call the global function if available
            if (typeof window.TamRankUpdateScoreCircle === 'function') {
                window.TamRankUpdateScoreCircle(score);
            }

            // Trigger event for TamRank Total Score widget
            $(document).trigger('tamrank:contentScoreUpdated', { score: score });
        },

        /**
         * Get score class based on score value
         */
        getScoreClass: function (score) {
            if (score >= 80) return 'score-excellent';
            if (score >= 60) return 'score-good';
            if (score >= 40) return 'score-needs-work';
            return 'score-poor';
        },

        /**
         * Get score color based on score value
         */
        getScoreColor: function (score) {
            if (score >= 80) return '#10b981'; // --tr-color-status-excellent
            if (score >= 60) return '#14b8a6'; // --tr-color-status-good
            if (score >= 40) return '#f59e0b'; // --tr-color-status-attention
            return '#f43f5e'; // --tr-color-status-improve
        },

        /**
         * Get score label based on score value
         */
        getScoreLabel: function (score) {
            if (typeof tamRankContent !== 'undefined' && tamRankContent.strings) {
                if (score >= 80) return tamRankContent.strings.excellent;
                if (score >= 60) return tamRankContent.strings.good;
                if (score >= 40) return tamRankContent.strings.attention;
                return tamRankContent.strings.improve;
            }
            // Fallback default
            if (score >= 80) return 'Excellent';
            if (score >= 60) return 'Good';
            if (score >= 40) return 'Attention needed';
            return 'Improvement needed';
        },

        /**
         * Update top issues display as expandable recommendations
         */
        updateTopIssues: function (issues) {
            const $container = $(this.config.selectors.issuesList);
            $container.empty();

            if (!issues || issues.length === 0) {
                $container.html(
                    '<div class="tam-content-no-issues">' +
                    this.getStatusIcon('success') +
                    '<span>' + tamRankContent.strings.noIssuesGoodJob + '</span>' +
                    '</div>'
                );
                return;
            }

            const limited = issues.slice(0, 5);
            const errors = limited.filter(function (i) { return i.type === 'error'; });
            const warnings = limited.filter(function (i) { return i.type !== 'error'; });
            const self = this;

            if (errors.length > 0) {
                const label = errors.length === 1
                    ? errors.length + ' ' + (tamRankContent.strings.critical_issue_singular || 'Critical issue')
                    : errors.length + ' ' + (tamRankContent.strings.critical_issues_plural || 'Critical issues');
                let groupHtml =
                    '<div class="tam-content-issues-group">' +
                    '<div class="tam-content-issues-group-header tam-content-issues-group-header--critical">' +
                    '<span class="tam-content-issues-group-dot"></span>' +
                    '<span class="tam-content-issues-group-label">' + label + '</span>' +
                    '<span class="tam-content-issues-group-line"></span>' +
                    '</div>';
                groupHtml += self.buildRecommendationCards(errors);
                groupHtml += '</div>';
                $container.append(groupHtml);
            }

            if (warnings.length > 0) {
                const label = warnings.length === 1
                    ? warnings.length + ' ' + (tamRankContent.strings.improvement_singular || 'Improvement point')
                    : warnings.length + ' ' + (tamRankContent.strings.improvement_plural || 'Improvement points');
                let groupHtml =
                    '<div class="tam-content-issues-group">' +
                    '<div class="tam-content-issues-group-header tam-content-issues-group-header--warning">' +
                    '<span class="tam-content-issues-group-dot"></span>' +
                    '<span class="tam-content-issues-group-label">' + label + '</span>' +
                    '<span class="tam-content-issues-group-line"></span>' +
                    '</div>';
                groupHtml += self.buildRecommendationCards(warnings);
                groupHtml += '</div>';
                $container.append(groupHtml);
            }
        },

        /**
         * Build HTML for recommendation cards
         */
        buildRecommendationCards: function (issues) {
            const self = this;
            let html = '';
            issues.forEach(function (issue) {
                const iconType = issue.type === 'error' ? 'error' : 'warning';
                const points = issue.points || issue.weight || 0;
                const tip = issue.tip || '';

                html +=
                    '<div class="tam-content-recommendation" data-recommendation-id="' + (issue.id || '') + '">' +
                    '<button type="button" class="tam-content-recommendation-header">' +
                    '<div class="tam-content-recommendation-icon">' + self.getStatusIcon(iconType) + '</div>' +
                    '<div class="tam-content-recommendation-content">' +
                    '<div class="tam-content-recommendation-title">' + self.escapeHtml(issue.title) + '</div>' +
                    '<div class="tam-content-recommendation-description">' + self.escapeHtml(issue.description) + '</div>' +
                    '</div>' +
                    '<div class="tam-content-recommendation-points">\u2191 +' + points + '% score</div>' +
                    '<div class="tam-content-recommendation-chevron">' + self.getChevronRightIcon() + '</div>' +
                    '</button>';

                if (tip) {
                    html +=
                        '<div class="tam-content-recommendation-tip" style="display: none;">' +
                        '<div class="tam-content-tip-box">' +
                        '<div class="tam-content-tip-icon">' + self.getLightbulbIcon() + '</div>' +
                        '<div class="tam-content-tip-content">' +
                        '<div class="tam-content-tip-label">' + (window.tamRank.i18n.how_to_fix || 'How to fix this?') + '</div>' +
                        '<div class="tam-content-tip-text">' + self.escapeHtml(tip) + '</div>' +
                        '</div>' +
                        '</div>' +
                        '</div>';
                }

                html += '</div>';
            });
            return html;
        },

        /**
         * Get chevron right icon SVG
         */
        getChevronRightIcon: function () {
            return '<svg class="tam-icon tam-icon-chevron-right" width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9 18L15 12L9 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>';
        },

        /**
         * Get lightbulb icon SVG
         */
        getLightbulbIcon: function () {
            return '<svg class="tam-icon tam-icon-lightbulb" width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9 21H15M12 3C8.13401 3 5 6.13401 5 10C5 12.38 6.19 14.47 8 15.74V17C8 17.55 8.45 18 9 18H15C15.55 18 16 17.55 16 17V15.74C17.81 14.47 19 12.38 19 10C19 6.13401 15.866 3 12 3Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>';
        },

        /**
         * Update categories and checks
         */
        updateCategories: function (categories, passedCount, totalChecks) {
            const $checksCount = $(this.config.selectors.checksCount);
            const $container = $(this.config.selectors.allChecks);

            // Update count
            $checksCount.text(passedCount + '/' + totalChecks + ' ' + tamRankContent.strings.passed);

            // Clear and rebuild
            $container.empty();

            const self = this;
            Object.keys(categories).forEach(function (categoryId) {
                const category = categories[categoryId];
                let checksHtml = '';

                category.checks.forEach(function (check) {
                    const statusLabel = self.getStatusLabel(check.status);
                    checksHtml +=
                        '<div class="tam-content-check tam-check-' + check.status + '">' +
                        '<div class="tam-content-check-icon">' + self.getStatusIcon(check.status) + '</div>' +
                        '<div class="tam-content-check-text">' + self.escapeHtml(check.label) + '</div>' +
                        '<div class="tam-content-check-status">' + statusLabel + '</div>' +
                        '</div>';
                });

                $container.append(
                    '<div class="tam-content-category">' +
                    '<div class="tam-content-category-header">' +
                    self.getCategoryIcon(category.icon) +
                    '<span class="tam-content-category-title">' + self.escapeHtml(category.title) + '</span>' +
                    '<span class="tam-content-category-score">' + category.passed + '/' + category.total + '</span>' +
                    '</div>' +
                    '<div class="tam-content-category-checks">' + checksHtml + '</div>' +
                    '</div>'
                );
            });
        },

        /**
         * Update details section
         */
        updateDetails: function (details) {
            if (!details) return;

            // Update heading tree
            if (details.headings) {
                this.updateHeadingTree(details.headings);
            }

            // Update intro snippet
            if (details.intro_snippet !== undefined) {
                $('#content-intro-snippet').text(details.intro_snippet);
            }

            // Update images list
            if (details.images !== undefined) {
                this.updateImagesList(details.images);
            }

            // Update internal links
            if (details.internal_links !== undefined) {
                this.updateLinksList(details.internal_links, 'internal');
            }

            // Update external links
            if (details.external_links !== undefined) {
                this.updateLinksList(details.external_links, 'external');
            }

            // Update word count
            if (details.word_count !== undefined) {
                $('#content-word-count').text(details.word_count + ' ' + (tamRankContent.strings.words || 'words'));
            }
        },

        /**
         * Update images list display
         */
        updateImagesList: function (images) {
            const $container = $('#content-images-list');
            const $section = $container.closest('.tam-content-detail-section');
            const $title = $section.find('.tam-content-detail-title');
            const self = this;

            // Update count in title
            const titleHtml = $title.html();
            const imagesLabel = tamRankContent.strings.images_count_label || 'Images (%d)';
            $title.html(fillPlaceholder(titleHtml, /Afbeeldingen \(\d+\)|Images \(\d+\)/, fillPlaceholder(imagesLabel, '%d', images.length)));

            $container.empty();

            if (!images || images.length === 0) {
                $container.html('<div class="tam-content-empty">' + tamRankContent.strings.noImages + '</div>');
                return;
            }

            let html = '<div class="tam-images-list">';
            images.forEach(function (image) {
                const hasAlt = image.alt && image.alt.length > 0;
                const isFilenameAlt = image.is_filename_alt || false;
                let itemClass = 'tam-image-item';
                if (!hasAlt) {
                    itemClass += ' tam-image-no-alt';
                } else if (isFilenameAlt) {
                    itemClass += ' tam-image-filename-alt';
                }

                let statusIcon, altText;
                if (hasAlt) {
                    statusIcon = isFilenameAlt ? self.getStatusIcon('warning') : self.getStatusIcon('success');
                    altText = 'alt="' + self.escapeHtml(image.alt) + '"';
                } else {
                    statusIcon = self.getStatusIcon('error');
                    altText = tamRankContent.strings.noAltText;
                }

                // Bepaal bestandsgrootte kleur
                const fileSizeStatus = image.file_size_status || 'unknown';
                const fileSizeFormatted = image.file_size_formatted || tamRankContent.strings.sizeUnknown;
                const hasWebp = image.has_webp || false;
                const hasLazyLoading = image.has_lazy_loading || false;
                const format = (image.format || '').toUpperCase();

                let sizeColor = '#25AC75'; // good = groen
                if (fileSizeStatus === 'error') {
                    sizeColor = '#DC7EA0'; // roze
                } else if (fileSizeStatus === 'warning') {
                    sizeColor = '#FAA530'; // oranje
                } else if (fileSizeStatus === 'info') {
                    sizeColor = '#3b82f6'; // blauw
                }

                // WebP badge
                let webpBadge = '';
                if (hasWebp || format === 'WEBP') {
                    webpBadge = '<span class="tam-image-badge tam-badge-success" style="display: inline-flex; padding: 2px 6px; border-radius: 8px; font-size: 9px; font-weight: 500; background: #e6f7ef; color: #25AC75;">WebP</span>';
                } else {
                    webpBadge = '<span class="tam-image-badge tam-badge-info" style="display: inline-flex; padding: 2px 6px; border-radius: 8px; font-size: 9px; font-weight: 500; background: #dbeafe; color: #3b82f6;">' + tamRankContent.strings.noWebP + '</span>';
                }

                // Lazy loading badge
                let lazyBadge = '';
                if (hasLazyLoading) {
                    lazyBadge = '<span class="tam-image-badge tam-badge-success" style="display: inline-flex; padding: 2px 6px; border-radius: 8px; font-size: 9px; font-weight: 500; background: #e6f7ef; color: #25AC75;">Lazy</span>';
                } else {
                    lazyBadge = '<span class="tam-image-badge tam-badge-warning" style="display: inline-flex; padding: 2px 6px; border-radius: 8px; font-size: 9px; font-weight: 500; background: #fff8eb; color: #b8860b;">' + tamRankContent.strings.noLazy + '</span>';
                }

                // Format badge (optioneel, in preview)
                let formatBadge = '';
                if (format) {
                    formatBadge = '<span class="tam-image-format-badge">' + format + '</span>';
                }

                html += '<div class="' + itemClass + '">' +
                    '<div class="tam-image-preview">' +
                    '<img src="' + self.escapeHtml(image.src) + '" alt="" loading="lazy">' +
                    formatBadge +
                    '</div>' +
                    '<div class="tam-image-info">' +
                    '<div class="tam-image-alt">' +
                    statusIcon +
                    '<span>' + altText + '</span>' +
                    '</div>' +
                    '<div class="tam-image-extra-info" style="margin-top: 8px; padding-top: 8px; border-top: 1px solid #ddd; text-align: center;">' +
                    '<span class="tam-image-size" style="display: block; margin-bottom: 6px; font-weight: 600; font-size: 11px; color: ' + sizeColor + ';">' + fileSizeFormatted + '</span>' +
                    '<div class="tam-image-badges" style="display: flex; flex-wrap: wrap; justify-content: center; gap: 4px;">' +
                    webpBadge +
                    lazyBadge +
                    '</div>' +
                    '</div>' +
                    '</div>' +
                    '</div>';
            });
            html += '</div>';

            $container.html(html);
        },

        /**
         * Update links list display
         */
        updateLinksList: function (links, type) {
            const containerId = type === 'internal' ? '#content-internal-links' : '#content-external-links';
            const $container = $(containerId);
            const $section = $container.closest('.tam-content-detail-section');
            const $title = $section.find('.tam-content-detail-title');
            const self = this;
            const labelType = type === 'internal' ? tamRankContent.strings.internalLinksLabel : tamRankContent.strings.externalLinksLabel;

            // Update count in title
            const titleHtml = $title.html();
            const regex = new RegExp(labelType + ' \\(\\d+\\)');
            $title.html(titleHtml.replace(regex, labelType + ' (' + links.length + ')'));

            $container.empty();

            if (!links || links.length === 0) {
                const emptyText = type === 'internal' ? tamRankContent.strings.noInternalLinks : tamRankContent.strings.noExternalLinks;
                $container.html('<div class="tam-content-empty">' + emptyText + '</div>');
                return;
            }

            let html = '<div class="tam-links-list">';
            links.forEach(function (link) {
                let statusClass = '';
                let statusIcon = self.getStatusIcon('success');

                if (link.status === 404) {
                    statusClass = 'tam-link-broken';
                    statusIcon = self.getStatusIcon('error');
                } else if (link.is_spam) {
                    statusClass = 'tam-link-spam';
                    statusIcon = self.getStatusIcon('warning');
                }

                const anchor = link.anchor || '(' + tamRankContent.strings.noAnchorText + ')';
                html += '<div class="tam-link-item ' + statusClass + '">' +
                    statusIcon +
                    '<span class="tam-link-anchor">' + self.escapeHtml(anchor) + '</span>' +
                    '<span class="tam-link-url">' + self.escapeHtml(link.url) + '</span>' +
                    (link.status === 404 ? '<span class="tam-link-status-badge">404</span>' : '') +
                    '</div>';
            });
            html += '</div>';

            $container.html(html);
        },

        /**
         * Update heading tree display
         */
        updateHeadingTree: function (headings) {
            const $container = $('#content-heading-tree');
            $container.empty();

            if (!headings || headings.length === 0) {
                $container.html('<div class="tam-content-no-headings">' + tamRankContent.strings.noHeadings + '</div>');
                return;
            }

            const self = this;
            headings.forEach(function (heading) {
                const level = heading.level || 2;
                const indent = (level - 1) * 20;
                const hasIssue = heading.issue ? 'has-issue' : '';

                $container.append(
                    '<div class="tam-content-heading-item ' + hasIssue + '" style="padding-left: ' + indent + 'px;">' +
                    '<span class="tam-content-heading-tag">H' + level + '</span>' +
                    '<span class="tam-content-heading-text">' + self.escapeHtml(heading.text) + '</span>' +
                    (heading.issue ? '<span class="tam-content-heading-issue">' + self.escapeHtml(heading.issue) + '</span>' : '') +
                    '</div>'
                );
            });
        },

        /**
         * Get status label
         */
        getStatusLabel: function (status) {
            const labels = {
                'success': tamRankContent.strings.statusOk,
                'warning': tamRankContent.strings.statusWarning,
                'error': tamRankContent.strings.statusError
            };
            return labels[status] || tamRankContent.strings.statusUnknown;
        },

        /**
         * Show loading state
         */
        showLoading: function () {
            $(this.config.selectors.loadingOverlay).show();
        },

        /**
         * Hide loading state
         */
        hideLoading: function () {
            $(this.config.selectors.loadingOverlay).hide();
        },

        /**
         * Show error message
         */
        showError: function (message) {
            TamRank.notify(message, 'error');
        },

        /**
         * Get status icon SVG
         */
        getStatusIcon: function (status) {
            const icons = {
                'success': '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#10b981" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline></svg>',
                'warning': '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#f59e0b" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="12"></line><line x1="12" y1="16" x2="12.01" y2="16"></line></svg>',
                'error': '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#f43f5e" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="15" y1="9" x2="9" y2="15"></line><line x1="9" y1="9" x2="15" y2="15"></line></svg>',
                'info': '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#3b82f6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg>'
            };
            return icons[status] || icons['info'];
        },

        /**
         * Get category icon SVG
         */
        getCategoryIcon: function (icon) {
            const icons = {
                'heading': '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M6 12h12M6 4v16M18 4v16"></path></svg>',
                'keyword': '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>',
                'readability': '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"></path><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"></path></svg>',
                'image': '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><circle cx="8.5" cy="8.5" r="1.5"></circle><polyline points="21 15 16 10 5 21"></polyline></svg>',
                'link': '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>',
                'length': '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="21" y1="10" x2="7" y2="10"></line><line x1="21" y1="6" x2="3" y2="6"></line><line x1="21" y1="14" x2="3" y2="14"></line><line x1="21" y1="18" x2="7" y2="18"></line></svg>',
                'technical': '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg>'
            };
            return icons[icon] || icons['heading'];
        },

        /**
         * Escape HTML helper
         */
        escapeHtml: function (text) {
            if (!text) return '';
            const div = document.createElement('div');
            div.textContent = text;
            return div.innerHTML;
        },

        /**
         * Debounce helper
         */
        debounce: function (func, wait) {
            let timeout;
            return function (...args) {
                const context = this;
                clearTimeout(timeout);
                timeout = setTimeout(() => func.apply(context, args), wait);
            };
        }
    };

    // Initialize when document is ready
    $(document).ready(function () {
        // Only initialize on post edit screens
        if ($('#tam-content-tab').length || $('.tam-meta-tabs').length) {
            TamRankContentTab.init();
        }
    });

    // Also initialize when Gutenberg is ready
    if (typeof wp !== 'undefined' && wp.domReady) {
        wp.domReady(function () {
            if ($('#tam-content-tab').length || $('.tam-meta-tabs').length) {
                TamRankContentTab.init();
            }
        });
    }

    // Export for external use
    window.TamRankContentTab = TamRankContentTab;

})(jQuery);
