(function(wp, settings) {
    "use strict";

    if (!wp || !wp.blocks || !wp.element || !wp.components || !(wp.blockEditor || wp.editor)) {
        return;
    }

    var blockName = "cryptocurrency-price-widget/price-widget";
    var el = wp.element.createElement;
    var Fragment = wp.element.Fragment;
    var useEffect = wp.element.useEffect;
    var useRef = wp.element.useRef;
    var useState = wp.element.useState;
    var __ = wp.i18n.__;
    var blockEditor = wp.blockEditor || wp.editor;
    var InspectorControls = blockEditor.InspectorControls;
    var useBlockProps = blockEditor.useBlockProps || function(props) {
        return props || {};
    };
    var registerBlockType = wp.blocks.registerBlockType;
    var BaseControl = wp.components.BaseControl;
    var Button = wp.components.Button;
    var ColorPalette = wp.components.ColorPalette;
    var ExternalLink = wp.components.ExternalLink;
    var PanelBody = wp.components.PanelBody;
    var TextControl = wp.components.TextControl;
    var ToggleControl = wp.components.ToggleControl;
    var suggestionCache = {};
    var assetMetaCache = {};

    var defaultBase = normalizeSymbols(settings.defaultBase, ["USD", "EUR", "CNY", "GBP"], 4);
    var defaultItems = normalizeSymbols(settings.defaultItems, ["BTC", "ETH", "LTC", "XMR", "DASH"], 15);

    var colors = [
        { name: __("Blue", "cryptocurrency-price-widget"), color: "#007BFF" },
        { name: __("Green", "cryptocurrency-price-widget"), color: "#28A745" },
        { name: __("Teal", "cryptocurrency-price-widget"), color: "#20C997" },
        { name: __("Cyan", "cryptocurrency-price-widget"), color: "#17A2B8" },
        { name: __("Orange", "cryptocurrency-price-widget"), color: "#FD7E14" },
        { name: __("Red", "cryptocurrency-price-widget"), color: "#DC3545" },
        { name: __("White", "cryptocurrency-price-widget"), color: "#FFFFFF" },
        { name: __("Dark", "cryptocurrency-price-widget"), color: "#343A40" }
    ];

    function toArray(value) {
        if (Array.isArray(value)) {
            return value;
        }

        if (typeof value === "string") {
            return value.split(",");
        }

        return [];
    }

    function normalizeSymbol(value) {
        var symbol = String(value && value.value ? value.value : value || "").trim().toLocaleUpperCase();

        try {
            return symbol.replace(/[^\p{L}\p{N}._$-]/gu, "");
        } catch (error) {
            return symbol.toUpperCase().replace(/[^A-Z0-9._$-]/g, "");
        }
    }

    function normalizeSymbols(value, fallback, limit) {
        var seen = {};
        var normalized = [];
        var source = toArray(value);

        source.forEach(function(item) {
            var symbol = normalizeSymbol(item);

            if (symbol && !seen[symbol]) {
                seen[symbol] = true;
                normalized.push(symbol);
            }
        });

        if (!normalized.length) {
            normalized = fallback.slice();
        }

        return normalized.slice(0, limit);
    }

    function resolveIcon(path, isFiat, iconUrl) {
        var fileName;
        var baseUrl;
        var separator;

        if (iconUrl) {
            return iconUrl;
        }

        if (!path) {
            return "";
        }

        if (isFiat) {
            fileName = String(path).split("/").pop() || "";
            fileName = fileName.replace(/\.[^.]+$/, ".webp");
            baseUrl = String(settings.fiatIconBase || "").replace(/\/+$/, "") + "/";

            return baseUrl + fileName;
        }

        if (/^https?:\/\//i.test(path)) {
            return path;
        }

        baseUrl = String(settings.cryptoIconBase || "https://www.cryptocompare.com").replace(/\/+$/, "");
        separator = String(path).charAt(0) === "/" ? "" : "/";

        return baseUrl + separator + path + (String(path).indexOf("?") === -1 ? "?width=128" : "&width=128");
    }

    function normalizeSuggestionItem(item) {
        var symbol = normalizeSymbol(item && (item.id || item.symbol || item.value || item.label));
        var path = String((item && (item.text || item.path)) || "");
        var iconUrl = String((item && (item.icon_url || item.iconUrl)) || "");
        var isFiat = !!(item && (item.fiat === 1 || item.fiat === "1" || item.fiat === true));

        if (!symbol) {
            return null;
        }

        return {
            label: symbol,
            value: symbol,
            symbol: symbol,
            name: String((item && item.name) || ""),
            path: path,
            iconUrl: iconUrl,
            fiat: isFiat,
            icon: resolveIcon(path, isFiat, iconUrl)
        };
    }

    function cacheAssetMeta(type, item) {
        if (item && item.symbol) {
            assetMetaCache[type + ":" + item.symbol] = item;
        }
    }

    function getAssetMeta(type, symbol) {
        return assetMetaCache[type + ":" + normalizeSymbol(symbol)] || null;
    }

    function seedAssetMeta(type, items) {
        (items || []).forEach(function(item) {
            cacheAssetMeta(type, normalizeSuggestionItem(item));
        });
    }

    seedAssetMeta("flags", settings.defaultBaseMeta || []);
    seedAssetMeta("coins", settings.defaultItemsMeta || []);

    function normalizeHex(value, fallback) {
        var normalized = String(value || "").replace(/^#/, "").toLowerCase().replace(/[^a-f0-9]/g, "");

        if (/^([a-f0-9]{3}|[a-f0-9]{6})$/.test(normalized)) {
            return normalized;
        }

        return fallback;
    }

    function boolToString(value) {
        return value === false ? "0" : "1";
    }

    function blockAttributes(attributes) {
        return {
            base: normalizeSymbols(attributes.base, defaultBase, 4),
            items: normalizeSymbols(attributes.items, defaultItems, 15),
            backgroundColor: normalizeHex(attributes.backgroundColor, "fff"),
            streaming: attributes.streaming !== false,
            striped: attributes.striped === true,
            rounded: attributes.rounded !== false,
            boxShadow: attributes.boxShadow !== false,
            border: attributes.border !== false,
            signature: attributes.signature !== false
        };
    }

    function setAttribute(setAttributes, key, value) {
        var update = {};
        update[key] = value;
        setAttributes(update);
    }

    function buildQuery(args) {
        return Object.keys(args).map(function(key) {
            return encodeURIComponent(key) + "=" + encodeURIComponent(args[key]);
        }).join("&");
    }

    function buildPreviewUrl(attributes) {
        var baseUrl = settings.previewUrlBase || "";

        if (!baseUrl) {
            return "";
        }

        return baseUrl + "?" + buildQuery({
            action: "CRCPW_block_preview",
            nonce: settings.nonce,
            base: attributes.base.join(","),
            items: attributes.items.join(","),
            backgroundColor: attributes.backgroundColor,
            streaming: boolToString(attributes.streaming),
            striped: boolToString(attributes.striped),
            rounded: boolToString(attributes.rounded),
            boxShadow: boolToString(attributes.boxShadow),
            border: boolToString(attributes.border),
            signature: boolToString(attributes.signature)
        });
    }

    function selectCurrentBlock(clientId) {
        var dispatch;

        if (!clientId || !wp.data || !wp.data.dispatch) {
            return;
        }

        dispatch = wp.data.dispatch("core/block-editor");

        if (dispatch && typeof dispatch.selectBlock === "function") {
            dispatch.selectBlock(clientId);
        }
    }

    function suggestionCacheKey(type, term, page) {
        return type + ":" + String(term || "").trim().toLocaleUpperCase() + ":" + String(page || 1);
    }

    function mergeSuggestionItems(current, next) {
        var seen = {};
        var merged = [];

        current.concat(next).forEach(function(item) {
            var symbol = item && item.symbol ? item.symbol : normalizeSymbol(item);

            if (symbol && !seen[symbol]) {
                seen[symbol] = true;
                merged.push(item);
            }
        });

        return merged;
    }

    function normalizeSuggestionPayload(data, type) {
        var suggestions = [];
        var seen = {};

        (data.results || []).forEach(function(item) {
            var suggestion = normalizeSuggestionItem(item);
            var symbol = suggestion && suggestion.symbol;

            if (symbol && !seen[symbol]) {
                seen[symbol] = true;
                cacheAssetMeta(type, suggestion);
                suggestions.push(suggestion);
            }
        });

        suggestions.sort(function(first, second) {
            if (first.symbol === second.symbol) {
                return 0;
            }

            return first.symbol > second.symbol ? 1 : -1;
        });

        return {
            suggestions: suggestions,
            hasMore: !!(data.pagination && data.pagination.more)
        };
    }

    function fetchAssetSuggestions(type, term, page) {
        var query = String(term || "").trim();
        var currentPage = page || 1;
        var key = suggestionCacheKey(type, query, currentPage);
        var url;

        if (!settings.ajaxUrl || !settings.nonce) {
            return Promise.resolve({ suggestions: [], hasMore: false });
        }

        if (suggestionCache[key]) {
            return Promise.resolve(suggestionCache[key]);
        }

        url = settings.ajaxUrl + "?" + buildQuery({
            action: "CRCPW_assets_data",
            nonce: settings.nonce,
            q: query,
            type: type,
            page: currentPage
        });

        return window.fetch(url, { credentials: "same-origin" })
            .then(function(response) {
                if (!response.ok) {
                    return { results: [], pagination: { more: false } };
                }

                return response.json();
            })
            .then(function(data) {
                var payload = normalizeSuggestionPayload(data, type);

                suggestionCache[key] = payload;
                return payload;
            })
            .catch(function() {
                return { suggestions: [], hasMore: false };
            });
    }

    function TokenFieldControl(props) {
        var suggestionState = useState([]);
        var suggestions = suggestionState[0];
        var setSuggestions = suggestionState[1];
        var queryState = useState("");
        var query = queryState[0];
        var setQuery = queryState[1];
        var pageState = useState(1);
        var page = pageState[0];
        var setPage = pageState[1];
        var moreState = useState(false);
        var hasMore = moreState[0];
        var setHasMore = moreState[1];
        var loadingState = useState(false);
        var loading = loadingState[0];
        var setLoading = loadingState[1];
        var openState = useState(false);
        var isOpen = openState[0];
        var setIsOpen = openState[1];
        var requestRef = useRef(0);
        var inputRef = useRef(null);
        var values = normalizeSymbols(props.value, props.fallback, props.limit);
        var allowCustom = props.allowCustom !== false;
        var selectedKey = values.join("|");
        var selectedLookup = {};

        values.forEach(function(symbol) {
            selectedLookup[symbol] = true;
        });

        function loadSuggestions(term, nextPage, replace) {
            var requestId;

            if (loading && !replace) {
                return;
            }

            requestRef.current += 1;
            requestId = requestRef.current;
            setLoading(true);

            fetchAssetSuggestions(props.type, term, nextPage).then(function(payload) {
                if (requestId !== requestRef.current) {
                    return;
                }

                setSuggestions(function(current) {
                    return replace ? payload.suggestions : mergeSuggestionItems(current, payload.suggestions);
                });
                setHasMore(payload.hasMore);
                setPage(nextPage);
                setLoading(false);
            });
        }

        useEffect(function() {
            loadSuggestions("", 1, true);
        }, []);

        useEffect(function() {
            var missing = values.filter(function(symbol) {
                return !getAssetMeta(props.type, symbol);
            });

            if (!missing.length) {
                return;
            }

            Promise.all(missing.map(function(symbol) {
                return fetchAssetSuggestions(props.type, symbol, 1);
            })).then(function(payloads) {
                var loaded = [];

                payloads.forEach(function(payload) {
                    loaded = loaded.concat(payload.suggestions || []);
                });

                if (loaded.length) {
                    setSuggestions(function(current) {
                        return mergeSuggestionItems(current, loaded);
                    });
                }
            });
        }, [props.type, selectedKey]);

        function addSymbol(item) {
            if (typeof item === "string" && !allowCustom) {
                return;
            }

            var suggestion = typeof item === "string" ? normalizeSuggestionItem({ id: item, fiat: props.type === "flags" }) : item;
            var symbol = suggestion && suggestion.symbol;

            if (!symbol || selectedLookup[symbol] || values.length >= props.limit) {
                return;
            }

            cacheAssetMeta(props.type, suggestion);
            props.onChange(values.concat([symbol]).slice(0, props.limit));
            setQuery("");
            setIsOpen(false);

            if (inputRef.current && inputRef.current.focus) {
                inputRef.current.focus();
            }
        }

        function removeSymbol(symbol) {
            props.onChange(values.filter(function(value) {
                return value !== symbol;
            }));
        }

        function removeLastSymbol() {
            if (values.length) {
                removeSymbol(values[values.length - 1]);
            }
        }

        function handleInputChange(event) {
            var value = event.target.value;

            setQuery(value);
            setIsOpen(true);
            loadSuggestions(value, 1, true);
        }

        function handleInputKeyDown(event) {
            if (event.key === "Backspace" && !query) {
                removeLastSymbol();
                event.preventDefault();
                return;
            }

            if (event.key === "Enter" || event.key === ",") {
                event.preventDefault();
                addSymbol(query);
            }
        }

        function handleMenuScroll(event) {
            var target = event.currentTarget;

            if (!hasMore || loading) {
                return;
            }

            if (target.scrollTop + target.clientHeight >= target.scrollHeight - 24) {
                loadSuggestions(query, page + 1, false);
            }
        }

        function renderToken(symbol) {
            var meta = getAssetMeta(props.type, symbol) || { symbol: symbol, name: "", icon: "" };

            return el("li", { key: symbol, className: "crcpw-block-token-picker__token" },
                meta.icon ? el("img", {
                    className: "crcpw-block-token-picker__token-icon",
                    alt: "",
                    loading: "lazy",
                    src: meta.icon
                }) : el("span", { className: "crcpw-block-token-picker__token-icon crcpw-block-token-picker__token-icon--placeholder" }),
                el("span", {
                    className: "crcpw-block-token-picker__token-label",
                    title: meta.name ? symbol + " - " + meta.name : symbol
                }, symbol),
                el("button", {
                    type: "button",
                    className: "crcpw-block-token-picker__remove",
                    "aria-label": __("Remove", "cryptocurrency-price-widget") + " " + symbol,
                    onClick: function() {
                        removeSymbol(symbol);
                    }
                }, "×")
            );
        }

        function renderSuggestion(item) {
            var selected = !!selectedLookup[item.symbol];
            var disabled = selected || values.length >= props.limit;

            return el("li", { key: item.symbol, className: "crcpw-block-token-picker__suggestion" },
                el("button", {
                    type: "button",
                    className: "crcpw-block-token-picker__suggestion-button",
                    disabled: disabled,
                    onMouseDown: function(event) {
                        event.preventDefault();
                    },
                    onClick: function() {
                        addSymbol(item);
                    }
                },
                    item.icon ? el("img", {
                        className: "crcpw-block-token-picker__suggestion-icon",
                        alt: "",
                        loading: "lazy",
                        src: item.icon
                    }) : el("span", { className: "crcpw-block-token-picker__suggestion-icon crcpw-block-token-picker__suggestion-icon--placeholder" }),
                    el("span", { className: "crcpw-block-token-picker__suggestion-copy" },
                        el("span", { className: "crcpw-block-token-picker__suggestion-symbol" }, item.symbol),
                        item.name && item.name !== item.symbol ? el("span", { className: "crcpw-block-token-picker__suggestion-name" }, item.name) : null
                    ),
                    selected ? el("span", { className: "crcpw-block-token-picker__suggestion-state" }, __("Selected", "cryptocurrency-price-widget")) : null
                )
            );
        }

        return el(BaseControl, {
            id: "crcpw-block-token-picker-" + props.type,
            label: props.label,
            help: props.help,
            className: "crcpw-block-token-field"
        },
            el("div", {
                className: "crcpw-block-token-picker",
                onBlur: function(event) {
                    if (!event.currentTarget.contains(event.relatedTarget)) {
                        setIsOpen(false);
                    }
                }
            },
                el("div", { className: "crcpw-block-token-picker__selected" },
                    el("ul", { className: "crcpw-block-token-picker__tokens" }, values.map(renderToken)),
                    el("div", { className: "crcpw-block-token-picker__actions" },
                        el("span", { className: "crcpw-block-token-picker__count", "aria-live": "polite" }, values.length + "/" + props.limit),
                        values.length ? el(Button, {
                            className: "crcpw-block-token-picker__clear",
                            onClick: function() {
                                props.onChange([]);
                            },
                            variant: "link"
                        }, __("Clear", "cryptocurrency-price-widget")) : null
                    )
                ),
                el("div", { className: "crcpw-block-token-picker__search" },
                    el("input", {
                        id: "crcpw-block-token-picker-" + props.type,
                        ref: inputRef,
                        type: "text",
                        className: "crcpw-block-token-picker__input",
                        autoComplete: "off",
                        placeholder: props.placeholder,
                        value: query,
                        onFocus: function() {
                            setIsOpen(true);
                            if (!suggestions.length) {
                                loadSuggestions(query, 1, true);
                            }
                        },
                        onChange: handleInputChange,
                        onKeyDown: handleInputKeyDown
                    }),
                    isOpen ? el("ul", {
                        className: "crcpw-block-token-picker__suggestions",
                        onScroll: handleMenuScroll
                    }, suggestions.length ? suggestions.map(renderSuggestion) : el("li", { className: "crcpw-block-token-picker__message" }, loading ? __("Searching...", "cryptocurrency-price-widget") : __("No matches found.", "cryptocurrency-price-widget"))) : null
                ),
                el("p", {
                    className: "crcpw-block-token-picker__status" + (values.length >= props.limit ? " is-warning" : ""),
                    "aria-live": "polite"
                }, values.length >= props.limit ? __("Remove one item to add another.", "cryptocurrency-price-widget") : ""),
                hasMore ? el(Button, {
                    className: "crcpw-block-token-field__more",
                    disabled: loading,
                    isBusy: loading,
                    onClick: function() {
                        setIsOpen(true);
                        loadSuggestions(query, page + 1, false);
                    },
                    variant: "secondary"
                }, loading ? __("Loading suggestions...", "cryptocurrency-price-widget") : __("Load more suggestions", "cryptocurrency-price-widget")) : null
            )
        );
    }

    function previewQuote(symbol, index) {
        var quotes = {
            BTC: { price: "$61,973.61", change: "0.47", up: true },
            ETH: { price: "$1,639.82", change: "-0.75", up: false },
            LTC: { price: "$42.42", change: "-0.30", up: false },
            XMR: { price: "$324.04", change: "1.97", up: true },
            DASH: { price: "$35.21", change: "-3.77", up: false },
            DOGE: { price: "$0.08454", change: "-0.68", up: false }
        };

        return quotes[symbol] || {
            price: "$" + (12 + index * 7).toFixed(2),
            change: index % 2 ? "-0.24" : "0.58",
            up: index % 2 === 0
        };
    }

    function previewIconStyle(symbol) {
        var colorsBySymbol = {
            BTC: "#f7931a",
            ETH: "#627eea",
            LTC: "#345d9d",
            XMR: "#ff6600",
            DASH: "#008de4",
            DOGE: "#ba9f33"
        };

        return {
            backgroundColor: colorsBySymbol[symbol] || "#f0f6fc",
            color: colorsBySymbol[symbol] ? "#fff" : "#135e96"
        };
    }

    function PreviewRow(props) {
        var quote = previewQuote(props.symbol, props.index || 0);
        var changeClass = quote.up ? " is-positive" : " is-negative";

        return el("div", { className: "crcpw-block-preview__row" },
            el("span", { className: "crcpw-block-preview__asset" },
                el("span", {
                    className: "crcpw-block-preview__asset-icon",
                    style: previewIconStyle(props.symbol),
                    "aria-hidden": "true"
                }, props.symbol.charAt(0) || "#"),
                el("strong", null, props.symbol)
            ),
            el("span", { className: "crcpw-block-preview__value", "aria-hidden": "true" },
                el("span", { className: "crcpw-block-preview__price" }, quote.price),
                el("span", { className: "crcpw-block-preview__change" + changeClass }, "(" + quote.change + "%)")
            )
        );
    }

    function NativePreview(props) {
        var attributes = props.attributes;
        var previewStyle = { backgroundColor: "#" + attributes.backgroundColor };
        var classes = ["crcpw-block-preview__card"];

        if (attributes.striped) {
            classes.push("is-striped");
        }

        if (attributes.rounded) {
            classes.push("is-rounded");
        }

        if (attributes.boxShadow) {
            classes.push("has-shadow");
        }

        if (attributes.border) {
            classes.push("has-border");
        }

        return el("div", { className: classes.join(" "), style: previewStyle },
            el("div", { className: "crcpw-block-preview__tabs" }, attributes.base.map(function(symbol) {
                return el("span", { key: symbol, className: "crcpw-block-preview__tab" }, symbol);
            })),
            el("div", { className: "crcpw-block-preview__rows" }, attributes.items.map(function(symbol, index) {
                return el(PreviewRow, { key: symbol, symbol: symbol, index: index });
            })),
            el("div", { className: "crcpw-block-preview__footer" },
                attributes.streaming ? el("span", { className: "crcpw-block-preview__live" }, "live") : el("span", null),
                el("span", { className: "crcpw-block-preview__brand" }, "CO-IN.IO")
            ),
            attributes.signature ? el("div", { className: "crcpw-attribution crcpw-attribution--editor" },
                el("span", { className: "crcpw-attribution__label" }, __("Source:", "cryptocurrency-price-widget")),
                " ",
                el(ExternalLink, { className: "crcpw-attribution__link", href: settings.currencyRateUrl }, "CurrencyRate.Today")
            ) : null
        );
    }

    function LivePreview(props) {
        var attributes = props.attributes;
        var previewUrl = buildPreviewUrl(attributes);
        var heightState = useState(360);
        var frameHeight = heightState[0];
        var setFrameHeight = heightState[1];
        var readyState = useState(false);
        var isFrameReady = readyState[0];
        var setIsFrameReady = readyState[1];
        var failedState = useState(false);
        var isFrameFailed = failedState[0];
        var setIsFrameFailed = failedState[1];
        var readyRef = useRef(false);
        var previewOrigin = "";

        if (!previewUrl) {
            return el(NativePreview, { attributes: attributes });
        }

        try {
            previewOrigin = new window.URL(previewUrl).origin;
        } catch (error) {
            previewOrigin = "";
        }

        useEffect(function() {
            var failureTimer;

            readyRef.current = false;
            setFrameHeight(360);
            setIsFrameReady(false);
            setIsFrameFailed(false);

            failureTimer = window.setTimeout(function() {
                if (!readyRef.current) {
                    setIsFrameFailed(true);
                }
            }, 10000);

            return function() {
                window.clearTimeout(failureTimer);
            };
        }, [previewUrl]);

        useEffect(function() {
            function handleMessage(event) {
                var data;
                var height;

                if (previewOrigin && event.origin && event.origin !== previewOrigin) {
                    return;
                }

                if (typeof event.data !== "string") {
                    return;
                }

                try {
                    data = JSON.parse(event.data);
                } catch (error) {
                    return;
                }

                height = parseInt(data && data.h, 10);

                if (height && height > 120) {
                    setFrameHeight(function(currentHeight) {
                        var nextHeight = Math.min(height + 16, 900);

                        return Math.abs(currentHeight - nextHeight) > 4 ? nextHeight : currentHeight;
                    });
                    readyRef.current = true;
                    setIsFrameReady(true);
                    setIsFrameFailed(false);
                }
            }

            window.addEventListener("message", handleMessage);

            return function() {
                window.removeEventListener("message", handleMessage);
            };
        }, [previewOrigin]);

        return el("div", { className: "crcpw-block-preview__live-shell" },
            !isFrameReady && !isFrameFailed ? el("div", { className: "crcpw-block-preview__loading", "aria-live": "polite" }, __("Loading live widget preview...", "cryptocurrency-price-widget")) : null,
            !isFrameReady && isFrameFailed ? el(NativePreview, { attributes: attributes }) : null,
            el("div", { className: "crcpw-block-preview__frame-wrap" + (isFrameReady ? "" : " is-preloading") },
                el("iframe", {
                    className: "crcpw-block-preview__frame",
                    title: __("Cryptocurrency price widget preview", "cryptocurrency-price-widget"),
                    src: previewUrl,
                    style: { minHeight: frameHeight + "px" },
                    tabIndex: "-1",
                    "aria-hidden": "true",
                    loading: "eager",
                    scrolling: "no",
                    onError: function() {
                        setIsFrameFailed(true);
                    }
                }),
                isFrameReady ? el("div", { className: "crcpw-block-preview__frame-shield", "aria-hidden": "true" }) : null
            )
        );
    }

    function AboutLinks() {
        return el(PanelBody, { title: __("About", "cryptocurrency-price-widget"), initialOpen: false },
            el("p", null, __("The widget runtime is provided by CO-IN.IO. Source attribution links to CurrencyRate.Today.", "cryptocurrency-price-widget")),
            el("p", null, el(ExternalLink, { href: settings.coInUrl }, "CO-IN.IO")),
            el("p", null, el(ExternalLink, { href: settings.currencyRateUrl }, "CurrencyRate.today")),
            el("p", null, el(ExternalLink, { href: settings.wordpressPluginUrl }, __("WordPress plugin page", "cryptocurrency-price-widget"))),
            el("p", null, el(ExternalLink, { href: settings.wordpressSupportUrl }, __("WordPress support page", "cryptocurrency-price-widget"))),
            el("p", null, el(ExternalLink, { href: settings.settingsUrl }, __("Plugin settings", "cryptocurrency-price-widget"))),
            el("p", null, __("If the free widget helps your site, please leave a quick rating.", "cryptocurrency-price-widget"))
        );
    }

    function Inspector(props) {
        var attributes = props.attributes;
        var setAttributes = props.setAttributes;

        return el(InspectorControls, null,
            el("div", { className: "crcpw-block-rate" },
                el(Button, {
                    href: settings.wordpressReviewUrl,
                    target: "_blank",
                    rel: "noopener noreferrer",
                    variant: "primary"
                }, __("Rate this plugin", "cryptocurrency-price-widget") + " ★★★★★")
            ),
            el(PanelBody, { title: __("Widget settings", "cryptocurrency-price-widget"), initialOpen: true },
                el(TokenFieldControl, {
                    label: __("Top row", "cryptocurrency-price-widget"),
                    help: __("Choose up to 4 fiat currencies.", "cryptocurrency-price-widget"),
                    placeholder: __("Add fiat currency", "cryptocurrency-price-widget"),
                    value: attributes.base,
                    fallback: defaultBase,
                    limit: 4,
                    type: "flags",
                    allowCustom: false,
                    onChange: function(value) {
                        setAttribute(setAttributes, "base", value);
                    }
                }),
                el(TokenFieldControl, {
                    label: __("Price list", "cryptocurrency-price-widget"),
                    help: __("Choose up to 15 crypto assets. Custom symbols are allowed for legacy compatibility.", "cryptocurrency-price-widget"),
                    placeholder: __("Add asset", "cryptocurrency-price-widget"),
                    value: attributes.items,
                    fallback: defaultItems,
                    limit: 15,
                    type: "coins",
                    allowCustom: true,
                    onChange: function(value) {
                        setAttribute(setAttributes, "items", value);
                    }
                }),
                el(BaseControl, {
                    id: "crcpw-block-background-color",
                    label: __("Background color", "cryptocurrency-price-widget")
                },
                    el(ColorPalette, {
                        colors: colors,
                        value: "#" + attributes.backgroundColor,
                        onChange: function(color) {
                            setAttribute(setAttributes, "backgroundColor", normalizeHex(color, "fff"));
                        }
                    }),
                    el(TextControl, {
                        label: __("Hex color", "cryptocurrency-price-widget"),
                        __next40pxDefaultSize: true,
                        value: attributes.backgroundColor,
                        onChange: function(value) {
                            setAttribute(setAttributes, "backgroundColor", normalizeHex(value, "fff"));
                        }
                    })
                ),
                el(ToggleControl, {
                    label: __("Streaming data", "cryptocurrency-price-widget"),
                    checked: attributes.streaming,
                    onChange: function(value) {
                        setAttribute(setAttributes, "streaming", value);
                    }
                }),
                el(ToggleControl, {
                    label: __("Striped rows", "cryptocurrency-price-widget"),
                    checked: attributes.striped,
                    onChange: function(value) {
                        setAttribute(setAttributes, "striped", value);
                    }
                }),
                el(ToggleControl, {
                    label: __("Rounded corners", "cryptocurrency-price-widget"),
                    checked: attributes.rounded,
                    onChange: function(value) {
                        setAttribute(setAttributes, "rounded", value);
                    }
                }),
                el(ToggleControl, {
                    label: __("Shadow", "cryptocurrency-price-widget"),
                    checked: attributes.boxShadow,
                    onChange: function(value) {
                        setAttribute(setAttributes, "boxShadow", value);
                    }
                }),
                el(ToggleControl, {
                    label: __("Border", "cryptocurrency-price-widget"),
                    checked: attributes.border,
                    onChange: function(value) {
                        setAttribute(setAttributes, "border", value);
                    }
                }),
                el(ToggleControl, {
                    label: __("Signature", "cryptocurrency-price-widget"),
                    checked: attributes.signature,
                    onChange: function(value) {
                        setAttribute(setAttributes, "signature", value);
                    }
                })
            ),
            AboutLinks()
        );
    }

    function Edit(props) {
        var attributes = blockAttributes(props.attributes || {});
        var blockProps = useBlockProps({
            className: "crcpw-block-preview",
            onClick: function() {
                selectCurrentBlock(props.clientId);
            },
            onMouseDown: function() {
                selectCurrentBlock(props.clientId);
            },
            onFocus: function() {
                selectCurrentBlock(props.clientId);
            }
        });

        return el(Fragment, null,
            el(Inspector, {
                attributes: attributes,
                setAttributes: props.setAttributes
            }),
            el("div", blockProps,
                el("div", { className: "crcpw-block-preview__header" },
                    el("strong", null, __("Cryptocurrency Price Widget", "cryptocurrency-price-widget")),
                    el("span", null, __("No API key required. Free browser-side rendering.", "cryptocurrency-price-widget"))
                ),
                el(LivePreview, { attributes: attributes })
            )
        );
    }

    registerBlockType(blockName, {
        apiVersion: 3,
        title: __("Cryptocurrency Price Widget", "cryptocurrency-price-widget"),
        description: __("Add live cryptocurrency prices with no API key.", "cryptocurrency-price-widget"),
        icon: "chart-line",
        category: "widgets",
        keywords: [__("crypto", "cryptocurrency-price-widget"), __("bitcoin", "cryptocurrency-price-widget"), __("price", "cryptocurrency-price-widget")],
        attributes: {
            base: { type: "array", default: defaultBase },
            items: { type: "array", default: defaultItems },
            backgroundColor: { type: "string", default: "fff" },
            streaming: { type: "boolean", default: true },
            striped: { type: "boolean", default: false },
            rounded: { type: "boolean", default: true },
            boxShadow: { type: "boolean", default: true },
            border: { type: "boolean", default: true },
            signature: { type: "boolean", default: true }
        },
        supports: {
            html: false
        },
        edit: Edit,
        save: function() {
            return null;
        }
    });
})(window.wp, window.CRCPWBlockSettings || {});
