(function (wp) {
    /**
     * Smart Convert – Currency & Unit Conversion - Gutenberg Block Logic
     *
     * Handles the registration and behavior of the conversion block in the editor.
     * Updated to use external CSS file (assets/css/smart-convert-currency-unit-conversion.css) instead of inline styles.
     *
     * @package           smart-convert-currency-unit-conversion
     * @author            Petr Novák
     * @copyright         2025 Petr Novák
     * @license           GPL-2.0-or-later
     * @licenseURI        https://www.gnu.org/licenses/gpl-2.0.html
     */

    var registerBlockType = wp.blocks.registerBlockType;
    var __ = wp.i18n.__;
    var _x = wp.i18n._x;
    var blockEditor = wp.blockEditor || wp.editor;
    var InspectorControls = blockEditor.InspectorControls;
    var el = wp.element.createElement;
    var Fragment = wp.element.Fragment;
    var components = wp.components;
    var PanelBody = components.PanelBody;
    var TextControl = components.TextControl;
    var ComboboxControl = components.ComboboxControl;
    var ServerSideRender = components.ServerSideRender || wp.editor.ServerSideRender;

    /**
     * ==============================================================================
     * LOCALIZATION STRINGS
     * ==============================================================================
     */

    var STRINGS = window.SmartConvertCurrencyUnitConversionBlockStrings || {
        blockTitle: tDual('Smart Convert - Currency & Unit Conversion'),
        blockDesc: tDual('The block allows you to easily insert a dynamic currency or unit converter directly into the page content with options to set default values, precision, and visual style using predefined templates.'),
        keyword1: tDual('currency'),
        keyword2: tDual('money'),
        settingsTitle: tDual('Smart Convert - Currency & Unit Conversion Settings'),
        livePreview: tDual('Live Preview'),
        labelAmount: tDual('Amount'),
        labelFrom: txDual('Original Currency / Unit', 'label.form.source_unit'),
        labelTo: txDual('Target Currency / Unit', 'label.form.target_unit'),
        labelDecimals: tDual('Number of Decimal Places'),
        labelOutput: tDual('Conversion Display Format'),
        hintCommon: tDual('Enter the value or amount to be converted to another unit or currency. Use a period to separate decimal places.'),
        hintOutput: tDual('Select the name of the template to be used for displaying the conversion from the autosuggest.'),
        badgeBuiltin: tDual('System'),
        badgeDefCurr: tDual('Default Template for Currency Conversions'),
        badgeDefUnit: tDual('Default Template for Unit Conversions')
    };

    function tDual(englishMsgid) {
        return __(englishMsgid, 'smart-convert-currency-unit-conversion');
    }

    function txDual(englishMsgid, context) {
        return _x(englishMsgid, context, 'smart-convert-currency-unit-conversion');
    }

    /**
     * ==============================================================================
     * SHARED DATA & HELPERS
     * ==============================================================================
     */
    var getScpSettings = function() {
        return window.SmartConvertCurrencyUnitConversionSettings || { 
            templates: [], 
            customUnits: [], 
            unitCatalogEnglishMap: {},
            defaultCurrency: 'USD',
            defaultCurrencyKey: 'default', 
            defaultUnitsKey: 'units' 
        };
    };

    function getTemplateOptions() {
        var settings = getScpSettings();
        if (!settings.templates || settings.templates.length === 0) return [];
        
        return settings.templates.map(function(template) {
            var label = template.name;
            if (template.type === 'builtin') {
                label += ' [' + STRINGS.badgeBuiltin + ']';
            }
            if (template.isDefaultCurrency) {
                label += ' [' + STRINGS.badgeDefCurr + ']';
            }
            if (template.isDefaultUnits) {
                label += ' [' + STRINGS.badgeDefUnit + ']';
            }
            return {
                value: template.key,
                label: label
            };
        });
    }

    var CURRENCY_CODES = ['ada','aed','afn','all','amd','aoa','ars','aud','awg','azn','bam','bbd','bdt','bgn','bhd','bif','bmd','bnb','bnd','bob','brl','bsd','btc','btn','bwp','byn','bzd','cad','cdf','chf','clp','cny','cop','crc','cup','cve','czk','djf','dkk','doge','dop','dzd','egp','ern','etb','eth','eur','fjd','fkp','gbp','gel','ghs','gip','gmd','gnf','gtq','gyd','hkd','hnl','htg','huf','idr','ils','inr','iqd','irr','isk','jmd','jod','jpy','kes','kgs','khr','kmf','kpw','krw','kwd','kyd','kzt','lak','lbp','lkr','lrd','lsl','lyd','mad','mdl','mga','mkd','mmk','mnt','mop','mru','mur','mvr','mwk','mxn','myr','mzn','nad','ngn','nio','nok','npr','nzd','omr','pab','pen','pgk','php','pkr','pln','pyg','qar','ron','rsd','rub','rwf','sar','sbd','scr','sdg','sek','sgd','shp','sle','sol','sos','srd','ssp','stn','svc','syp','szl','thb','tjs','tmt','tnd','top','trx','try','ttd','twd','tzs','uah','ugx','usd','usdc','usdt','uyu','uzs','ved','vnd','vuv','wst','xaf','xcd','xcg','xof','xpf','xrp','yer','zar','zmw','zwg'];

    function isCurrencyCode(value) {
        if (!value || !value.trim()) return false;
        var code = value.trim().toLowerCase();
        return CURRENCY_CODES.indexOf(code) !== -1;
    }

    // Base Unit Groups
    var UNIT_GROUPS_BASE = {
        length: ['km','m','dm','cm','mm','in','ft','yard','mi','nmi','angstrom','um','nm'],
        mass: ['t','kg','g','mg','ug','ounce','lb','st','ton_us','ton_uk'],
        volume: ['l','dl','cl','ml','gallon_us','gallon_uk','quart','pint','cups','fl_oz','tbsp','tsp'],
        area: ['sqkm','sqm','sqcm','sqmm','sqin','sqft','sqyd','acre','sqmi','hectare','are'],
        time: ['s','minute','h','day','week','month','year','decade','century'],
        speed: ['mps','kph','mph','fts','kn'],
        pressure: ['pa','kpa','mpa','bar','mbar','atm','psi','torr','mmhg'],
        energy: ['j','kj','calorie','kcal','wh','kwh','btu','ev'],
        power: ['w','kw','mw','hp'],
        density: ['kgcumm','gcumcm','lbcumft'],
        frequency: ['hz','khz','mhz','ghz'],
        data: ['bit','b','kb','mb','gb','tb','pb','kib','mib','gib'],
        angle: ['deg','radian','gradian'],
        temperature: ['C','F','K','R']
    };

    function getUnitData() {
        var settings = getScpSettings();
        var groups = JSON.parse(JSON.stringify(UNIT_GROUPS_BASE)); // Deep copy
        if (settings.customUnits && settings.customUnits.length > 0) {
            groups.custom = settings.customUnits;
        }
        return groups;
    }

    function formatUnitOption(item) {
        if (typeof item === 'object' && item !== null && item.value) {
            return {
                label: item.label || item.value,
                value: item.value
            };
        }
        return {
            label: getGlobalUnitLabel(item, false),
            value: item
        };
    }

    function getUnitGroup(fromValue) {
        if (!fromValue) return null;
        var groups = getUnitData();
        var lowerValue = fromValue.trim().toLowerCase();

        for (var group in groups) {
            if (!groups.hasOwnProperty(group)) continue;
            var arr = groups[group];
            for (var i = 0; i < arr.length; i++) {
                var item = arr[i];
                var code = (typeof item === 'object' && item !== null && item.value) ? item.value : String(item);
                if (code.toLowerCase() === lowerValue) {
                    return group;
                }
            }
        }
        return null;
    }
    
    function getGlobalUnitLabel(code, isCurrency) {
        if (!code) return '';
        var lower = code.toLowerCase();
        var key = 'global-unit-' + lower;
        var unitCatalogEnglishMap = getScpSettings().unitCatalogEnglishMap || {};
        var englishPhrase = unitCatalogEnglishMap[key] || '';
        var name = englishPhrase ? __(englishPhrase, 'smart-convert-currency-unit-conversion') : '';
        var displayCode = isCurrency ? lower.toUpperCase() : lower;
        if (name && englishPhrase && name !== englishPhrase) {
            return displayCode + ' (' + name + ')';
        }
        return displayCode;
    }

    var CURRENCY_OPTIONS = CURRENCY_CODES.map(function (code) {
        return {
            label: getGlobalUnitLabel(code, true),
            value: code.toUpperCase()
        };
    });

    function getAllUnitOptions() {
        var groups = getUnitData();
        return Object.keys(groups).reduce(function (acc, group) {
            return acc.concat(groups[group].map(formatUnitOption));
        }, []);
    }

    function getUnitOptionsForGroup(group) {
        var groups = getUnitData();
        if (!group || !groups[group]) return [];
        return groups[group].map(formatUnitOption);
    }

    function ensureOptionExists(options, value) {
        if (!value) return options;
        var exists = options.some(function(o) { 
            return o.value.toLowerCase() === value.toLowerCase(); 
        });
        if (!exists) {
            var newOptions = options.slice(); 
            newOptions.unshift({
                value: value,
                label: value + ' (Custom)'
            });
            return newOptions;
        }
        return options;
    }

    /**
     * ==============================================================================
     * HELPER: RENDER FIELD WITH HINT
     * Styles moved to external CSS class .smart-convert-currency-unit-conversion-field-wrapper, .smart-convert-currency-unit-conversion-field-label, etc.
     * ==============================================================================
     */
    function renderFieldWithHint(label, hint, controlComponent) {
        return el('div', { className: 'components-base-control smart-convert-currency-unit-conversion-field-wrapper' },
            el('div', { className: 'components-base-control__field' },
                // LABEL
                el('label', { className: 'components-base-control__label smart-convert-currency-unit-conversion-field-label' }, label),
                
                // HINT
                el('div', { className: 'smart-convert-currency-unit-conversion-inline-hint smart-convert-currency-unit-conversion-field-hint' }, hint),
                
                controlComponent
            )
        );
    }

    /**
     * ==============================================================================
     * BLOCK REGISTRATION
     * ==============================================================================
     */
    registerBlockType('smart-convert-currency-unit-conversion/convert', {
        title: STRINGS.blockTitle,
        description: STRINGS.blockDesc,
        icon: 'money-alt',
        category: 'widgets',
        keywords: [
            STRINGS.keyword1,
            STRINGS.keyword2,
            'convert'
        ],
        attributes: {
            amount: { type: 'string', default: '1' },
            from: { type: 'string', default: 'USD' },
            to: { type: 'string', default: '' },
            decimals: { type: 'string', default: '0' },
            output: { type: 'string', default: '' }
        },
        edit: function (props) {
            var attrs = props.attributes;
            var setAttributes = props.setAttributes;
            var settings = getScpSettings();

            var fromTrim = (attrs.from || '').trim();
            var fromIsCurrency = isCurrencyCode(fromTrim);
            var fromUnitGroup = getUnitGroup(fromTrim);
            
            var allUnits = getAllUnitOptions(); 
            var fromOptions = CURRENCY_OPTIONS.concat(allUnits);
            var toOptions = [];
            
            if (fromIsCurrency) {
                toOptions = CURRENCY_OPTIONS;
            } else if (fromUnitGroup) {
                toOptions = getUnitOptionsForGroup(fromUnitGroup);
            } else {
                toOptions = CURRENCY_OPTIONS.concat(allUnits);
            }

            fromOptions = ensureOptionExists(fromOptions, attrs.from);
            toOptions = ensureOptionExists(toOptions, attrs.to);

            function onChangeAmount(val) { setAttributes({ amount: val }); }
            function onChangeFrom(val) {
                var newFrom = val || '';
                setAttributes({ from: newFrom });
                if (isCurrencyCode(newFrom) && !attrs.to && settings.defaultCurrency) {
                    setAttributes({ to: settings.defaultCurrency.toUpperCase() });
                }
            }
            function onChangeTo(val) { setAttributes({ to: val || '' }); }
            function onChangeDecimals(val) { setAttributes({ decimals: val }); }
            function onChangeOutput(val) { setAttributes({ output: val || '' }); }

            return el(
                Fragment,
                null,
                // 1. Sidebar
                el(InspectorControls, null,
                    el(PanelBody, { title: STRINGS.settingsTitle, initialOpen: true },
                        el(TextControl, { label: STRINGS.labelAmount, value: attrs.amount, onChange: onChangeAmount }),
                        el(ComboboxControl, { label: STRINGS.labelFrom, value: attrs.from, options: fromOptions, onChange: onChangeFrom }),
                        el(ComboboxControl, { label: STRINGS.labelTo, value: attrs.to, options: toOptions, onChange: onChangeTo }),
                        el(ComboboxControl, { label: STRINGS.labelOutput, value: attrs.output, options: getTemplateOptions(), onChange: onChangeOutput })
                    )
                ),

                // 2. MAIN VISUAL EDITOR
                el('div', { className: 'smart-convert-currency-unit-conversion-block-wrapper' },
                    
                    // FORM UI - Uses external CSS classes
                    el('div', { className: 'smart-convert-currency-unit-conversion-block-editor-ui' },
                        
                        el('h4', null, STRINGS.blockTitle),
                        
                        // Amount
                        renderFieldWithHint(STRINGS.labelAmount, STRINGS.hintCommon,
                            el(TextControl, { value: attrs.amount, onChange: onChangeAmount })
                        ),

                        // From
                        renderFieldWithHint(STRINGS.labelFrom, STRINGS.hintCommon,
                            el(ComboboxControl, { value: attrs.from, options: fromOptions, onChange: onChangeFrom })
                        ),

                        // To
                        renderFieldWithHint(STRINGS.labelTo, STRINGS.hintCommon,
                            el(ComboboxControl, { value: attrs.to, options: toOptions, onChange: onChangeTo })
                        ),
                        
                        // Decimals
                         renderFieldWithHint(STRINGS.labelDecimals, STRINGS.hintCommon,
                            el(TextControl, { value: attrs.decimals, onChange: onChangeDecimals })
                        ),

                        // Output Template
                        renderFieldWithHint(STRINGS.labelOutput, STRINGS.hintOutput,
                            el(ComboboxControl, { 
                                value: attrs.output, 
                                options: getTemplateOptions(), 
                                onChange: onChangeOutput,
                                placeholder: STRINGS.hintOutput
                            })
                        )
                    ),

                    // LIVE PREVIEW
                    el('div', { className: 'smart-convert-currency-unit-conversion-block-preview-container' },
                        el('h5', { className: 'smart-convert-currency-unit-conversion-preview-title' }, STRINGS.livePreview + ':'),
                        
                        el(ServerSideRender, {
                            block: 'smart-convert-currency-unit-conversion/convert',
                            attributes: attrs
                        })
                    )
                )
            );
        },
        save: function () {
            return null; // Dynamic block
        }
    });
})(window.wp);