/**
 * SEO Fury — Schema Custom Builder (Конструктор)
 * Extracted for modular maintenance.
 *
 * Dependencies: jQuery, seoFuryData (localized)
 * Exposes: window.SeoFurySchemaBuilder
 */
(function ($) {
    'use strict';

    /* ========================================
       STATE
    ======================================== */
    var rowCounter  = 0;
    var groupCounter = 0;

    /* ========================================
       FULL SCHEMA.ORG TYPES LIST
    ======================================== */
    var allSchemaTypes = [
        'AboutPage','Action','AggregateRating','Article','AutoDealer','AutoRepair',
        'BankOrCreditUnion','Barber','BeautySalon','Blog','BlogPosting','Book',
        'BowlingAlley','BreadcrumbList','Brewery','BusStation','CafeOrCoffeeShop',
        'Car','Casino','CheckoutPage','Church','ClothingStore','CollectionPage',
        'CollegeOrUniversity','Comedy','ComputerStore','ContactPage','ContactPoint',
        'Corporation','Course','CreativeWork','DaySpa','Dentist','Department',
        'DigitalDocument','DrugStore','EducationalOrganization','Electrician',
        'EmergencyService','EmploymentAgency','EntertainmentBusiness','Event',
        'EventVenue','ExerciseGym','FAQPage','FastFoodRestaurant','FinancialService',
        'Florist','FoodEstablishment','FurnitureStore','GardenStore','GasStation',
        'GeneralContractor','GolfCourse','GovernmentOffice','GroceryStore',
        'HVACBusiness','HairSalon','HardwareStore','HealthClub','HighSchool',
        'HobbyShop','HomeAndConstructionBusiness','Hospital','Hostel','Hotel',
        'HousePainter','HowTo','IceCreamShop','InsuranceAgency','ItemList',
        'JewelryStore','JobPosting','LegalService','Library','LiquorStore',
        'LocalBusiness','Locksmith','LodgingBusiness','MediaObject','MedicalBusiness',
        'MedicalClinic','MedicalOrganization','MensClothingStore','MiddleSchool',
        'MobilePhoneStore','Mosque','Motel','MotorcycleDealer','MotorcycleRepair',
        'Movie','MovieRental','MovieTheater','MovingCompany','Museum','MusicAlbum',
        'MusicEvent','MusicGroup','MusicRecording','MusicVenue','NailSalon',
        'NewsArticle','NightClub','Notary','OfferCatalog','Optician','Organization',
        'PawnShop','PerformingArtsTheater','Person','PetStore','Pharmacy',
        'Physician','Place','Plumber','PostalAddress','Preschool','Product',
        'ProfessionalService','ProfilePage','QAPage','RealEstateAgent','Recipe',
        'Resort','Restaurant','Review','RoofingContractor','SaleEvent',
        'ScholarlyArticle','School','SearchResultsPage','SelfStorage','Service',
        'ShoeStore','ShoppingCenter','SkiResort','SocialEvent','SoftwareApplication',
        'SoftwareSourceCode','SportingGoodsStore','SportsActivityLocation',
        'SportsClub','SportsEvent','StadiumOrArena','Store','Synagogue',
        'TattooParlor','TaxiService','TelevisionStation','TheaterEvent',
        'TireShop','TouristAttraction','TouristInformationCenter','ToyStore',
        'TravelAgency','VideoObject','VisualArtsEvent','WebApplication','WebPage',
        'WebSite','WholesaleStore','Winery','Zoo'
    ];

    /* ========================================
       SHORTCODES DROPDOWN HTML (cached)
    ======================================== */
    var shortcodesHtml = '';
    function getShortcodesHtml() {
        if (shortcodesHtml) return shortcodesHtml;
        var html = '<div class="shortcode-dropdown-menu">' +
            '<div class="sf-shortcode-search-wrap"><input type="text" class="sf-shortcode-search" placeholder="' + (seoFuryData.i18n.searchPlaceholder || 'Search...') + '" /></div>';
        if (typeof seoFuryData !== 'undefined' && seoFuryData.shortcodeVariables) {
            $.each(seoFuryData.shortcodeVariables, function (i, item) {
                html += '<div class="shortcode-item" data-var="' + esc(item['var']) + '">' +
                    '<div class="shortcode-item-info"><strong>' + esc(item.label) + '</strong> ' +
                    '<span>' + esc(item.desc) + '</span></div>' +
                    '<code class="shortcode-item-var">' + esc(item['var']) + '</code></div>';
            });
        }
        html += '</div>';
        shortcodesHtml = html;
        return html;
    }

    function esc(str) {
        return $('<span>').text(str || '').html();
    }

    /* ========================================
       SCHEMA TYPES DROPDOWN (кнопка)
    ======================================== */
    function buildSchemaTypesDropdownHtml() {
        var html = '<div class="schema-types-dropdown">' +
            '<button type="button" class="button schema-types-dropdown-btn" title="' + (seoFuryData.i18n.selectSchemaType || 'Select Schema Type') + '">' +
            '<span class="dashicons dashicons-list-view" style="margin-top:3px;"></span>' +
            '</button>' +
            '<div class="schema-types-dropdown-menu" style="display:none;">' +
            '<div class="schema-types-search-wrap"><input type="text" class="schema-types-search" placeholder="' + (seoFuryData.i18n.searchTypePlaceholder || 'Search type...') + '" /></div>' +
            '<div class="schema-types-list">';

        for (var i = 0; i < allSchemaTypes.length; i++) {
            html += '<div class="schema-types-item" data-type="' + allSchemaTypes[i] + '">' + allSchemaTypes[i] + '</div>';
        }

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

    /* ========================================
       CREATE PROPERTY ROW
    ======================================== */
    function createPropertyRow(key, value, valueType) {
        rowCounter++;
        var rowId = 'builder-row-' + rowCounter;
        key = key || '';
        value = value || '';
        valueType = valueType || 'text';

        var html = '<div class="schema-builder-row" data-row-id="' + rowId + '">' +
            '<span class="schema-builder-drag dashicons dashicons-move" title="' + (seoFuryData.i18n.dragToReorder || 'Drag to reorder') + '"></span>' +
            '<input type="text" class="schema-builder-key" placeholder="' + (seoFuryData.i18n.propertyPlaceholder || 'Property (e.g. name)') + '" value="' + esc(key) + '">' +
            '<div class="input-with-dropdown schema-builder-value-wrap">' +
            '<input type="text" class="schema-builder-value" placeholder="' + (seoFuryData.i18n.valuePlaceholder || 'Value or %shortcode%') + '" value="' + esc(value) + '">' +
            '<button type="button" class="shortcode-dropdown-btn">' +
            '<span class="dashicons dashicons-arrow-down-alt2"></span>' +
            '</button>' +
            getShortcodesHtml() +
            '</div>' +
            '<select class="schema-builder-value-type">' +
            '<option value="text"' + (valueType === 'text' ? ' selected' : '') + '>' + (seoFuryData.i18n.typeText || 'Text') + '</option>' +
            '<option value="url"' + (valueType === 'url' ? ' selected' : '') + '>URL</option>' +
            '<option value="number"' + (valueType === 'number' ? ' selected' : '') + '>' + (seoFuryData.i18n.typeNumber || 'Number') + '</option>' +
            '<option value="date"' + (valueType === 'date' ? ' selected' : '') + '>' + (seoFuryData.i18n.typeDate || 'Date') + '</option>' +
            '<option value="boolean"' + (valueType === 'boolean' ? ' selected' : '') + '>Boolean</option>' +
            '<option value="array"' + (valueType === 'array' ? ' selected' : '') + '>' + (seoFuryData.i18n.typeArray || 'Array') + '</option>' +
            '</select>' +
            '<div class="schema-builder-row-actions">' +
            '<button type="button" class="button schema-builder-move-up" title="' + (seoFuryData.i18n.moveUp || 'Up') + '"><span class="dashicons dashicons-arrow-up-alt2"></span></button>' +
            '<button type="button" class="button schema-builder-move-down" title="' + (seoFuryData.i18n.moveDown || 'Down') + '"><span class="dashicons dashicons-arrow-down-alt2"></span></button>' +
            '<button type="button" class="button schema-builder-remove" title="' + (seoFuryData.i18n.deleteItem || 'Delete') + '"><span class="dashicons dashicons-trash"></span></button>' +
            '</div>' +
            '</div>';
        return html;
    }

    /* ========================================
       CREATE GROUP (recursive nesting)
    ======================================== */
    function createGroup(propKey, groupType, children) {
        groupCounter++;
        var groupId = 'builder-group-' + groupCounter;
        propKey = propKey || '';
        groupType = groupType || '';

        var html = '<div class="schema-builder-group" data-group-id="' + groupId + '">' +
            '<div class="schema-builder-group-header">' +
            '<span class="schema-builder-drag dashicons dashicons-move" title="' + (seoFuryData.i18n.dragToReorder || 'Drag to reorder') + '"></span>' +
            '<input type="text" class="schema-builder-group-key" placeholder="' + (seoFuryData.i18n.propertyPlaceholder || 'Property (e.g. name)') + '" value="' + esc(propKey) + '">' +
            '<input type="text" class="schema-builder-group-type" placeholder="@type (e.g. Person)" value="' + esc(groupType) + '">' +
            '<div class="schema-builder-row-actions">' +
            '<button type="button" class="button schema-builder-move-up" title="' + (seoFuryData.i18n.moveUp || 'Up') + '"><span class="dashicons dashicons-arrow-up-alt2"></span></button>' +
            '<button type="button" class="button schema-builder-move-down" title="' + (seoFuryData.i18n.moveDown || 'Down') + '"><span class="dashicons dashicons-arrow-down-alt2"></span></button>' +
            '<button type="button" class="button schema-builder-remove-group" title="' + (seoFuryData.i18n.deleteItem || 'Delete') + '"><span class="dashicons dashicons-trash"></span></button>' +
            '</div>' +
            '</div>' +
            '<div class="schema-builder-group-rows">';

        if (children && children.length > 0) {
            for (var i = 0; i < children.length; i++) {
                var child = children[i];
                if (child.type === 'group') {
                    html += createGroup(child.key, child.groupType, child.children);
                } else {
                    html += createPropertyRow(child.key, child.value, child.valueType);
                }
            }
        } else {
            html += createPropertyRow('', '', 'text');
        }

        html += '</div>' +
            '<div class="schema-builder-group-actions">' +
            '<button type="button" class="button schema-builder-add-group-prop">+ ' + (seoFuryData.i18n.addProperty || 'Property') + '</button>' +
            '<button type="button" class="button schema-builder-add-subgroup">+ ' + (seoFuryData.i18n.addGroup || 'Group') + '</button>' +
            '</div>' +
            '</div>';
        return html;
    }

    /* ========================================
       BUILD JSON (recursive)
    ======================================== */
    function buildJsonFromContainer($container) {
        var obj = {};
        // Accumulate array items: { 'mainEntity': { 0: {...}, 1: {...} } }
        // Used when group/row keys match the pattern  propName[N]
        var arrayAccum = {};

        $container.children('.schema-builder-row, .schema-builder-group').each(function () {
            var $el = $(this);

            if ($el.hasClass('schema-builder-row')) {
                var key = $el.find('> .schema-builder-key').val().trim();
                var value = $el.find('> .schema-builder-value-wrap .schema-builder-value').val().trim();
                var valueType = $el.children('.schema-builder-value-type').val() ||
                    $el.find('.schema-builder-value-type').first().val() || 'text';
                if (key && value) {
                    var arrMatch = key.match(/^(.+)\[(\d+)\]$/);
                    if (arrMatch) {
                        var arrKey = arrMatch[1], arrIdx = parseInt(arrMatch[2], 10);
                        if (!arrayAccum[arrKey]) arrayAccum[arrKey] = {};
                        arrayAccum[arrKey][arrIdx] = convertValue(value, valueType);
                    } else {
                        obj[key] = convertValue(value, valueType);
                    }
                }
            } else if ($el.hasClass('schema-builder-group')) {
                var groupKey = $el.find('> .schema-builder-group-header .schema-builder-group-key').val().trim();
                var groupType = $el.find('> .schema-builder-group-header .schema-builder-group-type').val().trim();
                if (!groupKey) return;

                var group = {};
                if (groupType) {
                    group['@type'] = groupType;
                }

                var $rows = $el.find('> .schema-builder-group-rows');
                var nested = buildJsonFromContainer($rows);
                $.extend(group, nested);

                var arrMatch = groupKey.match(/^(.+)\[(\d+)\]$/);
                if (arrMatch) {
                    var arrKey = arrMatch[1], arrIdx = parseInt(arrMatch[2], 10);
                    if (!arrayAccum[arrKey]) arrayAccum[arrKey] = {};
                    arrayAccum[arrKey][arrIdx] = group;
                } else {
                    obj[groupKey] = group;
                }
            }
        });

        // Merge accumulated array items into obj (sorted by numeric index)
        $.each(arrayAccum, function(key, items) {
            var maxIdx = Math.max.apply(null, Object.keys(items).map(Number));
            var arr = [];
            for (var i = 0; i <= maxIdx; i++) {
                if (items[i] !== undefined) arr.push(items[i]);
            }
            obj[key] = arr;
        });

        return obj;
    }

    function buildCustomJson() {
        var schemaType = $('#schema-builder-type').val().trim();
        if (!schemaType) return null;

        var schema = {
            '@context': 'https://schema.org',
            '@type': schemaType
        };

        var $container = $('#schema-builder-properties');
        var props = buildJsonFromContainer($container);
        $.extend(schema, props);

        return schema;
    }

    function convertValue(value, type) {
        switch (type) {
            case 'number':
                var num = parseFloat(value);
                return isNaN(num) ? value : num;
            case 'boolean':
                return value.toLowerCase() === 'true' || value === '1';
            case 'array':
                try {
                    var parsed = JSON.parse(value);
                    if (Array.isArray(parsed)) return parsed;
                } catch (e) {}
                return value.split(',').map(function (s) { return s.trim(); }).filter(Boolean);
            case 'date':
            case 'url':
            default:
                return value;
        }
    }

    /* ========================================
       GET / LOAD BUILDER DATA (recursive)
    ======================================== */
    function getDataFromContainer($container) {
        var props = [];

        $container.children('.schema-builder-row, .schema-builder-group').each(function () {
            var $el = $(this);

            if ($el.hasClass('schema-builder-row')) {
                props.push({
                    key: $el.find('> .schema-builder-key').val().trim(),
                    value: $el.find('> .schema-builder-value-wrap .schema-builder-value').val().trim(),
                    valueType: $el.find('.schema-builder-value-type').first().val()
                });
            } else if ($el.hasClass('schema-builder-group')) {
                var $rows = $el.find('> .schema-builder-group-rows');
                props.push({
                    key: $el.find('> .schema-builder-group-header .schema-builder-group-key').val().trim(),
                    type: 'group',
                    groupType: $el.find('> .schema-builder-group-header .schema-builder-group-type').val().trim(),
                    children: getDataFromContainer($rows)
                });
            }
        });

        return props;
    }

    function getBuilderData() {
        return {
            type: $('#schema-builder-type').val().trim(),
            properties: getDataFromContainer($('#schema-builder-properties'))
        };
    }

    function loadBuilderFromData(builderData) {
        $('#schema-builder-type').val(builderData.type || '');
        var $container = $('#schema-builder-properties');
        $container.empty();

        if (builderData.properties && builderData.properties.length > 0) {
            for (var i = 0; i < builderData.properties.length; i++) {
                var prop = builderData.properties[i];
                if (prop.type === 'group') {
                    $container.append(createGroup(prop.key, prop.groupType, prop.children));
                } else {
                    $container.append(createPropertyRow(prop.key, prop.value, prop.valueType));
                }
            }
        } else {
            $container.append(createPropertyRow('', '', 'text'));
        }

        updatePreview();
    }

    function clearBuilder() {
        $('#schema-builder-type').val('');
        var $container = $('#schema-builder-properties');
        $container.empty();
        $container.append(createPropertyRow('', '', 'text'));
        updatePreview();
    }

    /* ========================================
       PREVIEW
    ======================================== */
    function updatePreview() {
        var schema = buildCustomJson();
        var $preview = $('#schema-builder-json-output');
        if (schema) {
            $preview.text(JSON.stringify(schema, null, 2));
            $('#schema-builder-preview-section').show();
        } else {
            $preview.text('');
            $('#schema-builder-preview-section').hide();
        }
    }

    /* ========================================
       MOVE UP / DOWN
    ======================================== */
    function moveUp($el) {
        var $prev = $el.prev('.schema-builder-row, .schema-builder-group');
        if ($prev.length) {
            $el.insertBefore($prev);
            updatePreview();
        }
    }

    function moveDown($el) {
        var $next = $el.next('.schema-builder-row, .schema-builder-group');
        if ($next.length) {
            $el.insertAfter($next);
            updatePreview();
        }
    }

    /* ========================================
       EVENT BINDINGS
    ======================================== */
    function initEvents() {

        // Schema types dropdown toggle
        $(document).on('click', '.schema-types-dropdown-btn', function (e) {
            e.stopPropagation();
            var $menu = $(this).siblings('.schema-types-dropdown-menu');
            $('.schema-types-dropdown-menu').not($menu).hide();
            $menu.toggle();
            if ($menu.is(':visible')) {
                $menu.find('.schema-types-search').val('').trigger('input').focus();
            }
        });

        // Schema types dropdown search
        $(document).on('input', '.schema-types-search', function () {
            var q = $(this).val().toLowerCase();
            $(this).closest('.schema-types-dropdown-menu').find('.schema-types-item').each(function () {
                var text = $(this).text().toLowerCase();
                $(this).toggle(text.indexOf(q) !== -1);
            });
        });

        // Schema types dropdown select
        $(document).on('click', '.schema-types-item', function () {
            var type = $(this).data('type');
            // Find the type input within the same wrap (context-aware)
            var $typeInput = $(this).closest('.schema-builder-type-input-wrap').find('.schema-builder-type-input');
            if (!$typeInput.length) {
                $typeInput = $('#schema-builder-type');
            }
            $typeInput.val(type).trigger('input');
            $(this).closest('.schema-types-dropdown-menu').hide();
        });

        // Close dropdown on outside click
        $(document).on('click', function () {
            $('.schema-types-dropdown-menu').hide();
        });
        $(document).on('click', '.schema-types-dropdown-menu', function (e) {
            e.stopPropagation();
        });

        // Add property (top level)
        $(document).on('click', '#schema-builder-add-prop', function () {
            $('#schema-builder-properties').append(createPropertyRow('', '', 'text'));
        });

        // Add group (top level)
        $(document).on('click', '#schema-builder-add-group', function () {
            $('#schema-builder-properties').append(createGroup('', '', null));
        });

        // Add property inside group
        $(document).on('click', '.schema-builder-add-group-prop', function () {
            var $rows = $(this).closest('.schema-builder-group').children('.schema-builder-group-rows');
            $rows.append(createPropertyRow('', '', 'text'));
        });

        // Add sub-group inside group (nested)
        $(document).on('click', '.schema-builder-add-subgroup', function () {
            var $rows = $(this).closest('.schema-builder-group').children('.schema-builder-group-rows');
            $rows.append(createGroup('', '', null));
        });

        // Remove row
        $(document).on('click', '.schema-builder-remove', function () {
            $(this).closest('.schema-builder-row').remove();
            updatePreview();
        });

        // Remove group
        $(document).on('click', '.schema-builder-remove-group', function () {
            $(this).closest('.schema-builder-group').remove();
            updatePreview();
        });

        // Move up
        $(document).on('click', '.schema-builder-move-up', function (e) {
            e.preventDefault();
            var $item = $(this).closest('.schema-builder-row, .schema-builder-group');
            moveUp($item);
        });

        // Move down
        $(document).on('click', '.schema-builder-move-down', function (e) {
            e.preventDefault();
            var $item = $(this).closest('.schema-builder-row, .schema-builder-group');
            moveDown($item);
        });

        // Update preview on input
        $(document).on('input change',
            '#schema-builder-type, .schema-builder-key, .schema-builder-value, ' +
            '.schema-builder-value-type, .schema-builder-group-key, .schema-builder-group-type',
            function () {
                updatePreview();
            }
        );

        // Apply markup from builder
        $(document).on('click', '#schema-builder-apply', function () {
            var schema = buildCustomJson();
            if (!schema) {
                alert(seoFuryData.i18n.specifySchemaType || 'Please specify @type for schema');
                return;
            }

            var jsonStr = JSON.stringify(schema, null, 2);
            var builderData = getBuilderData();
            var schemaType = builderData.type || 'Custom';

            if (typeof window._seoFurySchemaCallbacks === 'object') {
                var cb = window._seoFurySchemaCallbacks;
                var editingId = cb.getBuilderEditingId ? cb.getBuilderEditingId() : null;

                if (editingId) {
                    // Update existing custom_builder item
                    var updatedItem = {
                        id: editingId,
                        type: 'custom_builder',
                        mode: 'custom_builder',
                        label: schemaType,
                        data: {},
                        custom: jsonStr,
                        builder_data: builderData
                    };
                    if (cb.updateBuilderItem) cb.updateBuilderItem(editingId, updatedItem);
                    if (cb.setBuilderEditingId) cb.setBuilderEditingId(null);
                    if (cb.setActiveSchemaId) cb.setActiveSchemaId(editingId);
                } else {
                    // Create new item
                    var newId = 'schema_' + Date.now() + '.' + Math.random().toString(36).substr(2, 5);
                    var newItem = {
                        id: newId,
                        type: 'custom_builder',
                        mode: 'custom_builder',
                        label: schemaType,
                        data: {},
                        custom: jsonStr,
                        builder_data: builderData
                    };
                    if (cb.storeActiveSchemaData) cb.storeActiveSchemaData();
                    if (cb.pushItem) cb.pushItem(newItem);
                    if (cb.setActiveSchemaId) cb.setActiveSchemaId(newId);
                    if (cb.applyActiveSchemaItem) cb.applyActiveSchemaItem(newItem);
                }
                if (cb.saveSchemaItems) cb.saveSchemaItems();
                if (cb.renderSchemaLists) cb.renderSchemaLists();
                if (cb.setSchemaMode) cb.setSchemaMode('custom_builder');
            }

            $('#seo_fury_schema_custom').val(jsonStr);

            // Close modal
            $('#seo-fury-schema-modal').hide();
            $('body').removeClass('modal-open').css('overflow', '');
        });

        // Init builder on load
        if ($('#schema-builder-properties').length && $('#schema-builder-properties').children().length === 0) {
            $('#schema-builder-properties').append(createPropertyRow('', '', 'text'));
        }
    }

    /* ========================================
       INJECT SCHEMA TYPES DROPDOWN INTO HTML
    ======================================== */
    function injectSchemaTypesDropdown() {
        $('.schema-builder-type-input-wrap').each(function () {
            var $wrap = $(this);
            if (!$wrap.find('.schema-types-dropdown').length) {
                $wrap.append(buildSchemaTypesDropdownHtml());
            }
        });
    }

    /* ========================================
       PUBLIC API
    ======================================== */
    window.SeoFurySchemaBuilder = {
        createPropertyRow: createPropertyRow,
        createGroup: createGroup,
        buildCustomJson: buildCustomJson,
        getBuilderData: getBuilderData,
        loadBuilderFromData: loadBuilderFromData,
        clearBuilder: clearBuilder,
        updatePreview: updatePreview,
        allSchemaTypes: allSchemaTypes,
        // Generic container-based API (for secondary builder instances)
        getDataFromContainer: getDataFromContainer,
        buildJsonFromContainer: buildJsonFromContainer,
        injectDropdownIntoWrap: function ($wrap) {
            if ($wrap && $wrap.length && !$wrap.find('.schema-types-dropdown').length) {
                $wrap.append(buildSchemaTypesDropdownHtml());
            }
        },
        injectSchemaTypesDropdown: injectSchemaTypesDropdown,
        init: function () {
            initEvents();
            injectSchemaTypesDropdown();
        }
    };

})(jQuery);
