import QtQuick
import QtQuick.Layouts
import Quickshell
import Quickshell.Wayland
import Quickshell.Io

import "../../config" as Cfg
import "../../components"

ModuleChip {
    id: root

    readonly property var cfg: Cfg.Config

    ConfigWriter {
        id: configWriter
    }

    width:  chipRow.implicitWidth + 24
    radius: panelRadius

    chipColor:         t.cryptoBg
    chipColorHovered:  t.cryptoBgHover
    chipBorderColor:   t.cryptoBorder
    chipBorderColorHovered: t.cryptoBorderHover
    chipHoverEnabled:  true
    chipTapAction:     () => cryptoPopup.toggle()
    popupOpen:         cryptoPopup.popupOpen
    chipAnimWidth:     true

    property var    localPairs:      [{ coin: "bitcoin", currency: "usd" }]
    property int    activeCoinIndex: 0
    readonly property string localCoinId:         localPairs.length > 0
        ? localPairs[activeCoinIndex % localPairs.length].coin
        : "bitcoin"
    readonly property string localActiveCurrency: localPairs.length > 0
        ? localPairs[activeCoinIndex % localPairs.length].currency
        : "usd"

    property string localVsCur:      "usd"
    property int    localDecimals:   cfg.cryptoDecimals
    property int    localRefreshSec: cfg.cryptoRefreshSec
    property int    localRotateSec:  cfg.cryptoRotateSec
    property bool   localShowIcon:   cfg.cryptoShowIcon

    function resolveWithPersistence() {
        root.localPairs      = Array.isArray(cfg.cryptoPairs) && cfg.cryptoPairs.length > 0 ? cfg.cryptoPairs : [{ coin: "bitcoin", currency: "usd" }]
        root.localVsCur      = root.localPairs[0].currency
        root.displayCurrency = root.localPairs[0].currency
        root.activeCoinIndex = 0
        root.localDecimals   = cfg.cryptoDecimals
        root.localRefreshSec = cfg.cryptoRefreshSec
        root.localRotateSec  = cfg.cryptoRotateSec
        root.localShowIcon   = cfg.cryptoShowIcon
    }

    function persistSettings() {
        const pairs      = root.localPairs
        const decimals   = Math.round(root.localDecimals)
        const refreshSec = Math.round(root.localRefreshSec)
        const rotateSec  = Math.round(root.localRotateSec)
        const showIcon   = root.localShowIcon

        const pairsQml = "[" + pairs.map(p =>
            '{ coin: "' + p.coin + '", currency: "' + p.currency + '" }'
        ).join(", ") + "]"

        configWriter.writeInts([
            { key: "cryptoDecimals",   value: decimals },
            { key: "cryptoRefreshSec", value: refreshSec },
            { key: "cryptoRotateSec",  value: rotateSec }
        ])
        configWriter.writeBool("cryptoShowIcon", showIcon)
        configWriter.writeArray("cryptoPairs", pairsQml)
    }

    property real   price:         -1
    property real   change24h:     0
    property real   high24h:       0
    property real   low24h:        0
    property real   marketCap:     0
    property real   volume24h:     0
    property int    rank:          0
    property real   circulatingSupply: 0
    property real   ath:           0
    property real   athChange:     0
    property string coinSymbol:    localCoinId.toUpperCase().slice(0, 4)
    property string coinName:      ""
    property string lastUpdated:   ""
    property string displayCurrency: "usd"
    property bool   loading:       false
    property bool   loadingVisible: false
    property bool   hasError:      false
    property var    sparklineData:  []
    property real   change7d:       0
    property var    _priceCache: ({})
    property int    _fetchGen:      0

    Timer {
        id: minLoadTimer
        interval: 2000
        repeat:   false
        onTriggered: { if (!root.loading) root.loadingVisible = false }
    }

    onLoadingChanged: {
        if (loading) {
            loadingVisible = true
            minLoadTimer.restart()
        } else {
            if (!minLoadTimer.running)
                loadingVisible = false
        }
    }

    function compactPrice(val) {
        if (val < 0)          return "—"
        const factor = Math.pow(10, localDecimals)
        if (val >= 1_000_000) {
            const n = Math.trunc(val * factor / 1_000_000)
            return (n / factor).toFixed(localDecimals) + "m"
        }
        if (val >= 1_000) {
            const n = Math.trunc(val * factor / 1_000)
            return (n / factor).toFixed(localDecimals) + "k"
        }
        return val.toFixed(Math.max(localDecimals, 2))
    }
    function fullPrice(val) {
        if (val < 0) return "—"
        return val.toLocaleString(Qt.locale(), "f", 2)
    }
    function compactLarge(val) {
        if (val <= 0)             return "—"
        if (val >= 1_000_000_000) return (val / 1_000_000_000).toFixed(2) + "B"
        if (val >= 1_000_000)     return (val / 1_000_000).toFixed(2)     + "M"
        if (val >= 1_000)         return (val / 1_000).toFixed(2)         + "k"
        return val.toFixed(2)
    }

    function safeNumber(val, fallback) {
        const n = Number(val)
        return (typeof n === "number" && isFinite(n)) ? n : fallback
    }

    function safeString(val, maxLen, fallback) {
        if (typeof val !== "string") return fallback
        return val.slice(0, maxLen).replace(/[\x00-\x1f\x7f-\x9f]/g, "")
    }

    function rotatePrev() {
        if (root.localPairs.length <= 1) return
        root.activeCoinIndex = (root.activeCoinIndex - 1 + root.localPairs.length) % root.localPairs.length
        root._applyFromCache()
        rotateTimer.restart()
    }

    function rotateNext() {
        if (root.localPairs.length <= 1) return
        root.activeCoinIndex = (root.activeCoinIndex + 1) % root.localPairs.length
        root._applyFromCache()
        rotateTimer.restart()
    }

    function _applyFromCache() {
        var key = root.localCoinId + "_" + root.localActiveCurrency
        var entry = root._priceCache[key]
        if (!entry) { console.log("Crypto: no cache entry for", key); return }
        console.log("Crypto: applying", key, "price=" + entry.price)
        price             = entry.price
        change24h         = entry.change24h
        high24h           = entry.high24h
        low24h            = entry.low24h
        marketCap         = entry.marketCap
        volume24h         = entry.volume24h
        rank              = entry.rank
        circulatingSupply = entry.circulatingSupply
        ath               = entry.ath
        athChange         = entry.athChange
        coinSymbol        = safeString(entry.symbol, 8, root.localCoinId).toUpperCase()
        coinName          = safeString(entry.name, 50, "")
        lastUpdated       = new Date().toLocaleTimeString(Qt.locale(), "HH:mm:ss")
        root.displayCurrency = root.localActiveCurrency
        sparklineData     = entry.sparkline || []
        change7d          = entry.change7d  || 0
        hasError = false
    }

    function fetchPrice() {
        loading  = true
        hasError = false
        _fetchGen++
        var myGen = _fetchGen

        var coinGroups = {}
        for (var i = 0; i < root.localPairs.length; i++) {
            var p = root.localPairs[i]
            if (!coinGroups[p.currency]) coinGroups[p.currency] = []
            var coinList = coinGroups[p.currency]
            if (coinList.indexOf(p.coin) === -1) coinList.push(p.coin)
        }

        var currencies = Object.keys(coinGroups)
        var pending = currencies.length

        if (pending === 0) { loading = false; hasError = true; return }

        for (var ci = 0; ci < currencies.length; ci++) {
            var cur = currencies[ci]
            var ids = coinGroups[cur].join(",")

            var url =
                "https://api.coingecko.com/api/v3/coins/markets" +
                "?vs_currency=" + encodeURIComponent(cur || "usd") +
                "&ids="         + encodeURIComponent(ids) +
                "&order=market_cap_desc&per_page=250&page=1" +
                "&sparkline=true&price_change_percentage=24h,7d"

            var xhr = new XMLHttpRequest()
            xhr._currency = cur
            xhr.timeout = 15000
            xhr.onreadystatechange = (function(xhr, cur, myGen) {
                return function() {
                    if (myGen !== root._fetchGen) return
                    if (xhr.readyState !== XMLHttpRequest.DONE) return
                    if (xhr.status !== 200) { hasError = true }
                    else {
                        try {
                            var text = xhr.responseText
                            if (text.length <= 65536) {
                                var data = JSON.parse(text)
                                if (Array.isArray(data)) {
                                    for (var di = 0; di < data.length; di++) {
                                        var coin = data[di]
                                        var key = coin.id + "_" + cur
                                        console.log("Crypto: cache", key, "price=" + coin.current_price)
                                        root._priceCache[key] = {
                                            price:      safeNumber(coin.current_price, -1),
                                            change24h:  safeNumber(coin.price_change_percentage_24h, 0),
                                            high24h:    safeNumber(coin.high_24h, 0),
                                            low24h:     safeNumber(coin.low_24h, 0),
                                            marketCap:  safeNumber(coin.market_cap, 0),
                                            volume24h:  safeNumber(coin.total_volume, 0),
                                            rank:       Math.trunc(safeNumber(coin.market_cap_rank, 0)),
                                            circulatingSupply: safeNumber(coin.circulating_supply, 0),
                                            ath:        safeNumber(coin.ath, 0),
                                            athChange:  safeNumber(coin.ath_change_percentage, 0),
                                            symbol:     safeString(coin.symbol, 8, coin.id),
                                            name:       safeString(coin.name, 50, ""),
                                            sparkline:  (coin.sparkline_in_7d && Array.isArray(coin.sparkline_in_7d.price))
                                                            ? coin.sparkline_in_7d.price : [],
                                            change7d:   safeNumber(coin.price_change_percentage_7d_in_currency, 0)
                                        }
                                    }
                                }
                            }
                        } catch (_) {}
                    }
                    if (--pending <= 0) {
                        loading = false
                        root._applyFromCache()
                    }
                }
            })(xhr, cur, myGen)

            xhr.open("GET", url)
            xhr.setRequestHeader("Accept", "application/json")
            xhr.send()
        }
    }

    Component.onCompleted: { resolveWithPersistence(); fetchPrice() }

    Timer {
        id: rotateTimer
        interval: root.localRotateSec * 1000
        running:  root.localRotateSec > 0 && root.localPairs.length > 1
        repeat:   true
        onTriggered: root.rotateNext()
    }

    Timer {
        id: refreshTimer
        interval: root.localRefreshSec * 1000
        running:  true
        repeat:   true
        triggeredOnStart: true
        onTriggered: root.fetchPrice()
    }

    onLocalRefreshSecChanged: refreshTimer.restart()
    onLocalRotateSecChanged: rotateTimer.restart()

    RowLayout {
        id: chipRow
        anchors.centerIn: parent
        spacing: 0

        SequentialAnimation on opacity {
            running: root.loadingVisible
            loops:   Animation.Infinite
            NumberAnimation { from: 1;    to: 0.25; duration: 500; easing.type: Easing.InOutSine }
            NumberAnimation { from: 0.25; to: 1;    duration: 500; easing.type: Easing.InOutSine }
        }

        Connections {
            target: root
            function onLoadingVisibleChanged() {
                if (!root.loadingVisible) chipRow.opacity = 1
            }
        }

        Text {
            visible:            root.localShowIcon
            text:               "󰿤"
            color:              t.cryptoIcon
            font.pixelSize:     14
            Layout.alignment:   Qt.AlignVCenter
            Layout.rightMargin: 7
        }

        Text {
            text:              root.coinSymbol + "/" + root.displayCurrency.toUpperCase() + ": "
            color:             t.cryptoLabel
            font.pixelSize:    12
            font.bold:         true
            verticalAlignment: Text.AlignVCenter
        }

        Text {
            text:              root.hasError ? "err" : root.price < 0 ? "…" : root.compactPrice(root.price)
            color:             t.cryptoValue
            font.pixelSize:    13
            font.bold:         true
            verticalAlignment: Text.AlignVCenter
        }

        Text {
            visible:           root.price >= 0
            text:              root.change24h >= 0 ? "▲" : "▼"
            color:             root.change24h >= 0 ? (t.cryptoUp) : (t.cryptoDown)
            font.pixelSize:    9
            font.bold:         true
            renderType:        Text.NativeRendering
            verticalAlignment: Text.AlignVCenter
            Layout.alignment:  Qt.AlignVCenter
            Layout.leftMargin: 4
            Behavior on color { ColorAnimation { duration: 200 } }
        }

    }

    StandardPopup {
        id: cryptoPopup
        ns: "crypto"
        chipRoot: root
        cardWidth: 300
        hasKeyboardFocus: true
        cardColor: t.cryptoPopupBg
        cardBorderColor: t.cryptoPopupBorder
        cardHeight: cardCol.implicitHeight + 24
        layerEnabled: true

        ColumnLayout {
            id: cardCol
                    anchors { left: parent.left; right: parent.right; top: parent.top }
                    anchors.margins:   16
                    anchors.topMargin: 16
                    spacing: 10

                        Rectangle {
                            Layout.fillWidth: true
                            height: 36
                            radius: 12
                            color:  t.cryptoFieldBg

                        RowLayout {
                            anchors.fill:    parent
                            anchors.margins: 4
                            spacing:         4

                            component TabBtn: Rectangle {
                                required property string label
                                required property int    tabIndex
                                property  string         icon: ""
                                Layout.fillWidth: true
                                height: 28
                                radius: 9

                                readonly property bool active: cryptoPopup.activeTab === tabIndex

                                color: active
                                       ? (t.accent)
                                       : (tm.containsMouse ? (t.cryptoFieldBgFocus) : "transparent")
                                Behavior on color { ColorAnimation { duration: 150 } }

                                border.color: active ? Qt.rgba(1, 1, 1, 0.18) : "transparent"
                                border.width: 1
                                Behavior on border.color { ColorAnimation { duration: 150 } }

                                scale: tm.pressed ? 0.93 : 1.0
                                Behavior on scale { NumberAnimation { duration: 90; easing.type: Easing.OutQuad } }

                                Row {
                                    anchors.centerIn: parent
                                    spacing: 5

                                    Text {
                                        anchors.verticalCenter: parent.verticalCenter
                                        visible:        parent.parent.icon !== ""
                                        text:           parent.parent.icon
                                        color:          parent.parent.active ? (t.cryptoTextOnAccent) : (t.cryptoPopupDim)
                                        font.pixelSize: 11
                                        opacity:        parent.parent.active ? 1.0 : 0.7
                                        Behavior on color   { ColorAnimation { duration: 150 } }
                                        Behavior on opacity { NumberAnimation { duration: 150 } }
                                    }

                                    Text {
                                        anchors.verticalCenter: parent.verticalCenter
                                        text:              parent.parent.label
                                        color:             parent.parent.active ? (t.cryptoTextOnAccent) : (t.cryptoPopupDim)
                                        font.pixelSize:    12
                                        font.bold:         parent.parent.active
                                        font.letterSpacing: parent.parent.active ? 0.4 : 0.0
                                        Behavior on color          { ColorAnimation { duration: 150 } }
                                        Behavior on font.letterSpacing { NumberAnimation { duration: 150 } }
                                    }
                                }

                                MouseArea {
                                    id: tm
                                    anchors.fill: parent; hoverEnabled: true
                                    cursorShape:  Qt.PointingHandCursor
                                    onClicked:    cryptoPopup.activeTab = tabIndex
                                }
                            }

                            TabBtn { label: "Price";    icon: "󰕾"; tabIndex: 0 }
                            TabBtn { label: "Settings"; icon: "󰒓"; tabIndex: 1 }
                        }
                    }

                    Item {
                        id: tabContainer
                        Layout.fillWidth: true
                        clip: true

                        Layout.preferredHeight: Math.max(priceContent.implicitHeight,
                                                         settingsContent.implicitHeight)

                    ColumnLayout {
                        id:      priceContent
                        width:   tabContainer.width
                        x:       cryptoPopup.activeTab === 0 ? 0 : -tabContainer.width
                        opacity: cryptoPopup.activeTab === 0 ? 1.0 : 0.0
                        Behavior on x       { NumberAnimation { duration: 260; easing.type: Easing.OutCubic } }
                        Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.OutCubic } }
                        spacing: 10

                        RowLayout {
                            Layout.fillWidth: true

                            Text {
                                text:             "󰿤"
                                color:            t.cryptoIcon
                                font.pixelSize:   22
                                Layout.alignment: Qt.AlignVCenter
                            }

                            ColumnLayout {
                                spacing:           1
                                Layout.fillWidth:  true
                                Layout.leftMargin: 8

                                Text {
                                    text:           root.coinSymbol + " / " + root.displayCurrency.toUpperCase()
                                    color:          t.cryptoPopupHeader
                                    font.pixelSize: 15
                                    font.bold:      true
                                }
                                Text {
                                    text:           root.coinName !== "" ? root.coinName : (root.localCoinId.charAt(0).toUpperCase() + root.localCoinId.slice(1))
                                    color:          t.cryptoPopupDim
                                    font.pixelSize: 11
                                }
                            }

                            Rectangle {
                                width:  badge.implicitWidth + 12
                                height: 22; radius: 11
                                color:  root.change24h >= 0 ? (t.cryptoUpBg) : (t.cryptoDownBg)

                                Text {
                                    id: badge
                                    anchors.centerIn: parent
                                    text:           (root.change24h >= 0 ? "▲ +" : "▼ ") + root.change24h.toFixed(2) + "%"
                                    color:          root.change24h >= 0 ? (t.cryptoUp) : (t.cryptoDown)
                                    font.pixelSize: 11
                                    font.bold:      true
                                    renderType:     Text.NativeRendering
                                }
                            }
                        }

                        Text {
                            Layout.fillWidth:    true
                            horizontalAlignment: Text.AlignHCenter
                            text:           root.price < 0 ? "Loading…" : root.displayCurrency.toUpperCase() + " " + root.fullPrice(root.price)
                            color:          t.cryptoPopupText
                            font.pixelSize: 24
                            font.bold:      true
                            font.family:    "monospace"
                        }

                        Rectangle { Layout.fillWidth: true; height: 1; color: t.calSeparator }

                        component StatRow: RowLayout {
                            property string label: ""
                            property string value: ""
                            Layout.fillWidth: true
                            Text { text: label; color: t.cryptoPopupDim; font.pixelSize: 12; Layout.fillWidth: true }
                            Text { text: value; color: t.cryptoPopupText; font.pixelSize: 12; font.bold: true; font.family: "monospace"; renderType: Text.NativeRendering }
                        }

                        StatRow { label: "Rank";       value: root.rank > 0 ? "#" + root.rank : "—" }
                        StatRow { label: "24h High";   value: root.high24h  > 0 ? root.fullPrice(root.high24h)  : "—" }
                        StatRow { label: "24h Low";    value: root.low24h   > 0 ? root.fullPrice(root.low24h)   : "—" }
                        StatRow { label: "Market Cap"; value: root.compactLarge(root.marketCap)  }
                        StatRow { label: "24h Volume"; value: root.compactLarge(root.volume24h)  }
                        StatRow { label: "Circ. Supply"; value: root.circulatingSupply > 0 ? root.compactLarge(root.circulatingSupply) + " " + root.coinSymbol : "—" }

                        RowLayout {
                            Layout.fillWidth: true
                            Text { text: "ATH"; color: t.cryptoPopupDim; font.pixelSize: 12; Layout.fillWidth: true }
                            Text {
                                text:           root.ath > 0 ? root.fullPrice(root.ath) : "—"
                                color:          t.cryptoPopupText
                                font.pixelSize: 12; font.bold: true; font.family: "monospace"
                            }
                            Text {
                                visible:        root.ath > 0
                                text:           "(" + root.athChange.toFixed(2) + "%)"
                                color:          t.cryptoDown
                                font.pixelSize: 11; font.bold: true; font.family: "monospace"
                            }
                        }

                        ColumnLayout {
                            Layout.fillWidth: true
                            spacing: 5

                            RowLayout {
                                Layout.fillWidth: true
                                Text {
                                    text:           "24h Range"
                                    color:          t.cryptoPopupDim
                                    font.pixelSize: 12
                                    renderType:     Text.NativeRendering
                                    Layout.fillWidth: true
                                }
                                Text {
                                    visible:        root.high24h > root.low24h && root.price >= 0
                                    text:           ((root.price - root.low24h) / (root.high24h - root.low24h) * 100).toFixed(1) + "% of range"
                                    color:          t.cryptoPopupDim
                                    font.pixelSize: 11
                                    renderType:     Text.NativeRendering
                                }
                            }

                            Item {
                                Layout.fillWidth: true
                                height: 6

                                Rectangle {
                                    anchors.fill: parent
                                    radius:       3
                                    color:        t.cryptoRangeTrack
                                }

                                Rectangle {
                                    height: parent.height
                                    radius: 3
                                    color:  root.change24h >= 0
                                            ? (t.cryptoUp)
                                            : (t.cryptoDown)
                                    width:  (root.high24h > root.low24h && root.price >= 0)
                                            ? Math.max(radius * 2,
                                              Math.min(parent.width,
                                                (root.price - root.low24h) / (root.high24h - root.low24h)
                                                * parent.width))
                                            : 0
                                    Behavior on width { NumberAnimation { duration: 500; easing.type: Easing.OutCubic } }
                                }
                            }

                            RowLayout {
                                Layout.fillWidth: true
                                Text {
                                    text:           root.low24h  > 0 ? root.fullPrice(root.low24h)  : "—"
                                    color:          t.cryptoDown
                                    font.pixelSize: 10
                                    font.family:    "monospace"
                                    renderType:     Text.NativeRendering
                                }
                                Item { Layout.fillWidth: true }
                                Text {
                                    text:           root.high24h > 0 ? root.fullPrice(root.high24h) : "—"
                                    color:          t.cryptoUp
                                    font.pixelSize: 10
                                    font.family:    "monospace"
                                    renderType:     Text.NativeRendering
                                }
                            }
                        }

                        Rectangle { Layout.fillWidth: true; height: 1; color: t.calSeparator }

                        ColumnLayout {
                            Layout.fillWidth: true
                            spacing: 5

                            RowLayout {
                                Layout.fillWidth: true
                                Text {
                                    text:           "7d Chart"
                                    color:          t.cryptoPopupDim
                                    font.pixelSize: 12
                                    Layout.fillWidth: true
                                }
                                Rectangle {
                                    visible:        root.sparklineData.length > 1
                                    width:          badge7d.implicitWidth + 12
                                    height:         20; radius: 10
                                    color:          root.change7d >= 0 ? (t.cryptoUpBg) : (t.cryptoDownBg)
                                    Text {
                                        id: badge7d
                                        anchors.centerIn: parent
                                        text:           (root.change7d >= 0 ? "▲ +" : "▼ ") + root.change7d.toFixed(2) + "%"
                                        color:          root.change7d >= 0 ? (t.cryptoUp) : (t.cryptoDown)
                                        font.pixelSize: 10
                                        font.bold:      true
                                    }
                                }
                            }

                            Canvas {
                                id:               sparklineCanvas
                                Layout.fillWidth: true
                                height:           52

                                property var    prices:    root.sparklineData
                                property bool   isUp:      root.change7d >= 0
                                property string upColor:   t.cryptoUp   || "#4ade80"
                                property string downColor: t.cryptoDown || "#f87171"

                                onPricesChanged:   requestPaint()
                                onIsUpChanged:     requestPaint()
                                onUpColorChanged:  requestPaint()
                                onDownColorChanged:requestPaint()

                                onPaint: {
                                    var ctx = getContext("2d")
                                    ctx.clearRect(0, 0, width, height)
                                    var pts = prices
                                    if (!pts || pts.length < 2) {
                                        ctx.fillStyle = Qt.rgba(1, 1, 1, 0.06)
                                        ctx.beginPath()
                                        ctx.roundedRect(0, 0, width, height, 6, 6)
                                        ctx.fill()
                                        return
                                    }
                                    var minP = pts[0], maxP = pts[0]
                                    for (var i = 1; i < pts.length; i++) {
                                        if (pts[i] < minP) minP = pts[i]
                                        if (pts[i] > maxP) maxP = pts[i]
                                    }
                                    var range = maxP - minP
                                    if (range === 0) range = 1
                                    var pad = 4, pw = width - pad * 2, ph = height - pad * 2
                                    var lineColor = isUp ? upColor : downColor

                                    ctx.beginPath()
                                    for (var j = 0; j < pts.length; j++) {
                                        var x = pad + (j / (pts.length - 1)) * pw
                                        var y = pad + ph - ((pts[j] - minP) / range) * ph
                                        if (j === 0) ctx.moveTo(x, y)
                                        else ctx.lineTo(x, y)
                                    }
                                    ctx.lineTo(pad + pw, pad + ph)
                                    ctx.lineTo(pad,      pad + ph)
                                    ctx.closePath()
                                    var grad = ctx.createLinearGradient(0, 0, 0, height)
                                    grad.addColorStop(0,   Qt.rgba(
                                        isUp ? 0.29 : 0.97,
                                        isUp ? 0.87 : 0.44,
                                        isUp ? 0.50 : 0.44, 0.22))
                                    grad.addColorStop(1,   Qt.rgba(0, 0, 0, 0))
                                    ctx.fillStyle = grad
                                    ctx.fill()

                                    ctx.beginPath()
                                    for (var k = 0; k < pts.length; k++) {
                                        var lx = pad + (k / (pts.length - 1)) * pw
                                        var ly = pad + ph - ((pts[k] - minP) / range) * ph
                                        if (k === 0) ctx.moveTo(lx, ly)
                                        else ctx.lineTo(lx, ly)
                                    }
                                    ctx.strokeStyle = lineColor
                                    ctx.lineWidth   = 1.5
                                    ctx.lineJoin    = "round"
                                    ctx.stroke()

                                    var lx2 = pad + pw
                                    var ly2 = pad + ph - ((pts[pts.length - 1] - minP) / range) * ph
                                    ctx.beginPath()
                                    ctx.arc(lx2, ly2, 3, 0, Math.PI * 2)
                                    ctx.fillStyle = lineColor
                                    ctx.fill()
                                }
                            }
                        }

                        Rectangle { Layout.fillWidth: true; height: 1; color: t.calSeparator }

                        RowLayout {
                            Layout.fillWidth: true

                            Text {
                                text:             root.hasError ? "⚠ fetch error" : "Updated " + (root.lastUpdated || "—")
                                color:            t.cryptoPopupDim
                                font.pixelSize:   11
                                Layout.fillWidth: true
                            }

                            Rectangle {
                                visible: root.localPairs.length > 1
                                width: 26; height: 26; radius: 8
                                color: prevMouse.containsMouse
                                    ? (prevMouse.pressed ? (t.accent) : (t.cryptoFieldBgFocus))
                                    : "transparent"
                                Behavior on color { ColorAnimation { duration: 120 } }

                                Text {
                                    anchors.centerIn: parent
                                    text: "‹"
                                    color: t.cryptoIcon
                                    font.pixelSize: 14
                                }

                                MouseArea {
                                    id: prevMouse
                                    anchors.fill: parent; hoverEnabled: true; cursorShape: Qt.PointingHandCursor
                                    onClicked: root.rotatePrev()
                                }
                            }

                            Rectangle {
                                visible: root.localPairs.length > 1
                                width: 26; height: 26; radius: 8
                                color: nextMouse.containsMouse
                                    ? (nextMouse.pressed ? (t.accent) : (t.cryptoFieldBgFocus))
                                    : "transparent"
                                Behavior on color { ColorAnimation { duration: 120 } }

                                Text {
                                    anchors.centerIn: parent
                                    text: "›"
                                    color: t.cryptoIcon
                                    font.pixelSize: 14
                                }

                                MouseArea {
                                    id: nextMouse
                                    anchors.fill: parent; hoverEnabled: true; cursorShape: Qt.PointingHandCursor
                                    onClicked: root.rotateNext()
                                }
                            }

                            Rectangle {
                                id: refreshBtn
                                width: 26; height: 26; radius: 8
                                color: rMouse.containsMouse
                                       ? (rMouse.pressed ? (t.accent) : (t.cryptoFieldBgFocus))
                                       : "transparent"
                                Behavior on color { ColorAnimation { duration: 120 } }

                                Text {
                                    id: refreshIcon
                                    anchors.centerIn: parent
                                    text:             "󰑐"
                                    color:            t.cryptoIcon
                                    font.pixelSize:   14

                                    RotationAnimator {
                                        id:      spinAnim
                                        target:  refreshIcon
                                        from:    0; to: 360
                                        duration: 600
                                        easing.type: Easing.OutCubic
                                        running: false
                                    }
                                }

                                MouseArea {
                                    id: rMouse
                                    anchors.fill: parent; hoverEnabled: true; cursorShape: Qt.PointingHandCursor
                                    onClicked: {
                                        spinAnim.restart()
                                        root.fetchPrice()
                                    }
                                }
                            }
                        }
                    }

                    ColumnLayout {
                        id:      settingsContent
                        width:   tabContainer.width
                        height:  tabContainer.height
                        x:       cryptoPopup.activeTab === 1 ? 0 : tabContainer.width
                        opacity: cryptoPopup.activeTab === 1 ? 1.0 : 0.0
                        Behavior on x       { NumberAnimation { duration: 260; easing.type: Easing.OutCubic } }
                        Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.OutCubic } }
                        spacing: 12

                        component FieldRow: ColumnLayout {
                            property string label:       ""
                            property string placeholder: ""
                            property alias  fieldText:   fi.text
                            spacing:          4
                            Layout.fillWidth: true

                            Text {
                                text:                label
                                color:               t.cryptoPopupDim
                                font.pixelSize:      11
                                font.capitalization: Font.AllUppercase
                            }

                            Rectangle {
                                Layout.fillWidth: true
                                height:           30
                                radius:           8
                                color:            fi.activeFocus ? (t.cryptoFieldBgFocus) : (t.cryptoFieldBg)
                                border.color:     fi.activeFocus ? (t.accent) : "transparent"
                                border.width:     1
                                Behavior on color        { ColorAnimation { duration: 120 } }
                                Behavior on border.color { ColorAnimation { duration: 120 } }

                                TextInput {
                                    id: fi
                                    anchors { fill: parent; leftMargin: 10; rightMargin: 10; topMargin: 7; bottomMargin: 7 }
                                    color:          t.cryptoPopupText
                                    font.pixelSize: 12
                                    font.family:    "monospace"
                                    selectionColor: t.accent
                                    clip:           true

                                    Text {
                                        anchors.fill:      parent
                                        text:              parent.parent.parent.placeholder
                                        color:             t.cryptoPlaceholder
                                        font.pixelSize:    12
                                        font.family:       "monospace"
                                        visible:           fi.text === "" && !fi.activeFocus
                                        verticalAlignment: Text.AlignVCenter
                                    }
                                }
                            }
                        }

                        component StepRow: RowLayout {
                            property string label:  ""
                            property int    value:  1
                            property int    minVal: 0
                            property int    maxVal: 999
                            signal stepped(int v)
                            Layout.fillWidth: true

                            Text { text: label; color: t.cryptoPopupDim; font.pixelSize: 12; Layout.fillWidth: true }

                            Rectangle {
                                width: 24; height: 24; radius: 7
                                color: mm.containsMouse ? (mm.pressed ? (t.accent) : (t.cryptoFieldBgFocus)) : (t.cryptoFieldBg)
                                Behavior on color { ColorAnimation { duration: 100 } }
                                Text { anchors.centerIn: parent; text: "−"; font.pixelSize: 14; font.bold: true; color: t.cryptoPopupText }
                                MouseArea { id: mm; anchors.fill: parent; hoverEnabled: true; cursorShape: Qt.PointingHandCursor; onClicked: if (value > minVal) stepped(value - 1) }
                            }

                            Rectangle {
                                width: 54; height: 24; radius: 6; color: t.cryptoFieldBg
                                Text { anchors.centerIn: parent; text: value; color: t.cryptoPopupText; font.pixelSize: 12; font.bold: true; font.family: "monospace" }
                            }

                            Rectangle {
                                width: 24; height: 24; radius: 7
                                color: pm.containsMouse ? (pm.pressed ? (t.accent) : (t.cryptoFieldBgFocus)) : (t.cryptoFieldBg)
                                Behavior on color { ColorAnimation { duration: 100 } }
                                Text { anchors.centerIn: parent; text: "+"; font.pixelSize: 14; font.bold: true; color: t.cryptoPopupText }
                                MouseArea { id: pm; anchors.fill: parent; hoverEnabled: true; cursorShape: Qt.PointingHandCursor; onClicked: if (value < maxVal) stepped(value + 1) }
                            }
                        }

                        component ToggleRow: RowLayout {
                            property string label:   ""
                            property bool   checked: false
                            signal toggled(bool v)
                            Layout.fillWidth: true

                            Text { text: label; color: t.cryptoPopupDim; font.pixelSize: 12; Layout.fillWidth: true }

                            Rectangle {
                                width: 36; height: 20; radius: 10
                                color: checked ? (t.accent) : (t.cryptoFieldBgFocus)
                                Behavior on color { ColorAnimation { duration: 150 } }

                                Rectangle {
                                    width: 14; height: 14; radius: 7; color: "#ffffffff"
                                    anchors.verticalCenter: parent.verticalCenter
                                    x: checked ? parent.width - 17 : 3
                                    Behavior on x { NumberAnimation { duration: 150; easing.type: Easing.OutCubic } }
                                }

                                MouseArea { anchors.fill: parent; cursorShape: Qt.PointingHandCursor; onClicked: toggled(!checked) }
                            }
                        }

                        ColumnLayout {
                            Layout.fillWidth: true
                            spacing: 8

                            Text {
                                text:                "Pairs to cycle"
                                color:               t.cryptoPopupDim
                                font.pixelSize:      11
                                font.capitalization: Font.AllUppercase
                            }

                            ColumnLayout {
                                Layout.fillWidth: true
                                spacing: 8

                                Item {
                                    Layout.fillWidth: true
                                    height: 28
                                    clip: true

                                    Rectangle {
                                        anchors { left: parent.left; top: parent.top; bottom: parent.bottom }
                                        width: 12; z: 2
                                        gradient: Gradient {
                                            orientation: Gradient.Horizontal
                                            GradientStop { position: 0.0; color: t.cryptoPopupBg }
                                            GradientStop { position: 1.0; color: "transparent" }
                                        }
                                        visible: chipScroll.contentX > 0
                                    }
                                    Rectangle {
                                        anchors { right: parent.right; top: parent.top; bottom: parent.bottom }
                                        width: 12; z: 2
                                        gradient: Gradient {
                                            orientation: Gradient.Horizontal
                                            GradientStop { position: 0.0; color: "transparent" }
                                            GradientStop { position: 1.0; color: t.cryptoPopupBg }
                                        }
                                        visible: chipScroll.contentX < chipScroll.contentWidth - chipScroll.width - 1
                                    }

                                    Flickable {
                                        id: chipScroll
                                        anchors.fill: parent
                                        contentWidth:  chipRow2.implicitWidth
                                        contentHeight: height
                                        clip: true
                                        flickableDirection: Flickable.HorizontalFlick
                                        boundsBehavior: Flickable.StopAtBounds

                                        Row {
                                            id: chipRow2
                                            spacing: 8

                                            Repeater {
                                                model: root.localPairs
                                                delegate: Item {
                                                    readonly property bool isActive:
                                                        index === root.activeCoinIndex % Math.max(1, root.localPairs.length)

                                                    height: 24
                                                    width:  chipLabel.implicitWidth + dotSpace.width + 6
                                                            + (root.localPairs.length > 1 ? 18 : 0)

                                                    Rectangle {
                                                        id: dotSpace
                                                        anchors.verticalCenter: parent.verticalCenter
                                                        x: 0; width: 5; height: 5; radius: 3
                                                        color: isActive ? (t.accent) : "#33ffffff"
                                                        Behavior on color { ColorAnimation { duration: 150 } }
                                                    }

                                                    Text {
                                                        id: chipLabel
                                                        anchors.verticalCenter: parent.verticalCenter
                                                        x: dotSpace.width + 5
                                                        text:           (modelData.coin ?? "?") + "/" + (modelData.currency ?? "?").toUpperCase()
                                                        color:          isActive
                                                                        ? (t.accent)
                                                                        : (t.cryptoPopupText)
                                                        font.pixelSize: 12
                                                        font.bold:      isActive
                                                        font.family:    "monospace"
                                                        Behavior on color { ColorAnimation { duration: 150 } }
                                                    }

                                                    Rectangle {
                                                        visible: root.localPairs.length > 1
                                                        anchors { right: parent.right
                                                                  verticalCenter: parent.verticalCenter }
                                                        width: 14; height: 14; radius: 4
                                                        color: rmChipMouse.containsMouse ? (t.cryptoChipRemoveBg) : "transparent"
                                                        Behavior on color { ColorAnimation { duration: 100 } }
                                                        Text {
                                                            anchors.centerIn: parent
                                                            text: "×"; font.pixelSize: 11; font.bold: true
                                                            color: t.cryptoDown
                                                        }
                                                        MouseArea {
                                                            id: rmChipMouse
                                                            anchors.fill: parent; hoverEnabled: true
                                                            cursorShape:  Qt.PointingHandCursor
                                                            onClicked: {
                                                                let arr = root.localPairs.slice()
                                                                arr.splice(index, 1)
                                                                root.localPairs = arr
                                                                if (root.activeCoinIndex >= arr.length)
                                                                    root.activeCoinIndex = 0
                                                                root.fetchPrice()
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }

                                Item {
                                    Layout.fillWidth: true
                                    height: 3
                                    visible: chipScroll.contentWidth > chipScroll.width

                                    Rectangle {
                                        anchors.fill: parent
                                        radius: 2
                                        color: t.cryptoFieldBg
                                    }

                                    Rectangle {
                                        height: parent.height
                                        radius: 2
                                        color: t.accent
                                        opacity: 0.7

                                        readonly property real ratio: chipScroll.width / Math.max(1, chipScroll.contentWidth)
                                        width: Math.max(16, parent.width * ratio)

                                        x: (parent.width - width) *
                                           (chipScroll.contentWidth > chipScroll.width
                                            ? chipScroll.contentX / (chipScroll.contentWidth - chipScroll.width)
                                            : 0)

                                        Behavior on x { NumberAnimation { duration: 80 } }
                                    }
                                }
                            }

                            ColumnLayout {
                                Layout.fillWidth: true
                                spacing: 4

                                Text {
                                    text:                "Coin ID"
                                    color:               t.cryptoPopupDim
                                    font.pixelSize:      11
                                    font.capitalization: Font.AllUppercase
                                }

                                Rectangle {
                                    Layout.fillWidth: true
                                    height: 30; radius: 8
                                    color:        addCoinInput.activeFocus ? (t.cryptoFieldBgFocus) : (t.cryptoFieldBg)
                                    border.color: addCoinInput.activeFocus ? (t.accent) : "transparent"
                                    border.width: 1
                                    Behavior on color        { ColorAnimation { duration: 120 } }
                                    Behavior on border.color { ColorAnimation { duration: 120 } }

                                    TextInput {
                                        id: addCoinInput
                                        anchors { fill: parent; leftMargin: 10; rightMargin: 10; topMargin: 7; bottomMargin: 7 }
                                        color:          t.cryptoPopupText
                                        font.pixelSize: 12; font.family: "monospace"
                                        selectionColor: t.accent
                                        clip: true

                                        Text {
                                            anchors.fill:      parent
                                            text:              "e.g. bitcoin, monero, solana"
                                            color:             t.cryptoPlaceholder
                                            font.pixelSize:    12; font.family: "monospace"
                                            visible:           parent.text === "" && !parent.activeFocus
                                            verticalAlignment: Text.AlignVCenter
                                        }

                                        onAccepted: addCurrencyInput.forceActiveFocus()
                                    }
                                }
                            }

                            ColumnLayout {
                                Layout.fillWidth: true
                                spacing: 4

                                Text {
                                    text:                "Currency"
                                    color:               t.cryptoPopupDim
                                    font.pixelSize:      11
                                    font.capitalization: Font.AllUppercase
                                }

                                RowLayout {
                                    Layout.fillWidth: true
                                    spacing: 6

                                    Rectangle {
                                        Layout.fillWidth: true
                                        height: 30; radius: 8
                                        color:        addCurrencyInput.activeFocus ? (t.cryptoFieldBgFocus) : (t.cryptoFieldBg)
                                        border.color: addCurrencyInput.activeFocus ? (t.accent) : "transparent"
                                        border.width: 1
                                        Behavior on color        { ColorAnimation { duration: 120 } }
                                        Behavior on border.color { ColorAnimation { duration: 120 } }

                                        TextInput {
                                            id: addCurrencyInput
                                            anchors { fill: parent; leftMargin: 10; rightMargin: 10; topMargin: 7; bottomMargin: 7 }
                                            color:          t.cryptoPopupText
                                            font.pixelSize: 12; font.family: "monospace"
                                            selectionColor: t.accent
                                            clip: true

                                            Text {
                                                anchors.fill:      parent
                                                text:              "e.g. usd, eur, brl"
                                                color:             t.cryptoPlaceholder
                                                font.pixelSize:    12; font.family: "monospace"
                                                visible:           parent.text === "" && !parent.activeFocus
                                                verticalAlignment: Text.AlignVCenter
                                            }

                                            onAccepted: {
                                                const c   = addCoinInput.text.trim().toLowerCase()
                                                const cur = addCurrencyInput.text.trim().toLowerCase() || root.localVsCur
                                                if (c !== "") {
                                                    root.localPairs       = root.localPairs.concat([{ coin: c, currency: cur }])
                                                    addCoinInput.text     = ""
                                                    addCurrencyInput.text = ""
                                                    root.fetchPrice()
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            Rectangle {
                                Layout.fillWidth: true
                                Layout.topMargin: 4
                                height: 32; radius: 9
                                color: addPairMouse.containsMouse
                                       ? (addPairMouse.pressed ? (t.accent) : (t.cryptoFieldBgFocus))
                                       : (t.cryptoApplyIdleBg)
                                Behavior on color { ColorAnimation { duration: 130 } }
                                Text {
                                    anchors.centerIn: parent
                                    text:             "+ Add Pair"
                                    color:            addPairMouse.containsMouse ? (t.cryptoTextOnAccent) : (t.cryptoPopupText)
                                    font.pixelSize:   12; font.bold: true
                                    Behavior on color { ColorAnimation { duration: 130 } }
                                }
                                MouseArea {
                                    id: addPairMouse
                                    anchors.fill: parent; hoverEnabled: true; cursorShape: Qt.PointingHandCursor
                                    onClicked: {
                                        const c   = addCoinInput.text.trim().toLowerCase()
                                        const cur = addCurrencyInput.text.trim().toLowerCase() || root.localVsCur
                                        if (c !== "") {
                                            root.localPairs       = root.localPairs.concat([{ coin: c, currency: cur }])
                                            addCoinInput.text     = ""
                                            addCurrencyInput.text = ""
                                            root.fetchPrice()
                                        }
                                    }
                                }
                            }

                        }

                        Item { Layout.fillHeight: true }

                        Rectangle { Layout.fillWidth: true; height: 1; color: t.calSeparator }

                        StepRow {
                            label:  "Decimals in label"
                            value:  root.localDecimals
                            minVal: 0
                            maxVal: 8
                            onStepped: (v) => root.localDecimals = v
                        }

                        RowLayout {
                            Layout.fillWidth: true

                            Text {
                                text:             "Refresh (seconds)"
                                color:            t.cryptoPopupDim
                                font.pixelSize:   12
                                Layout.fillWidth: true
                            }

                            Rectangle {
                                width: 24; height: 24; radius: 7
                                color: decMouse.containsMouse
                                       ? (decMouse.pressed ? (t.accent) : (t.cryptoFieldBgFocus))
                                       : (t.cryptoFieldBg)
                                Behavior on color { ColorAnimation { duration: 100 } }
                                Text { anchors.centerIn: parent; text: "−"; font.pixelSize: 14; font.bold: true; color: t.cryptoPopupText }
                                MouseArea {
                                    id: decMouse
                                    anchors.fill: parent; hoverEnabled: true; cursorShape: Qt.PointingHandCursor
                                    onClicked: if (root.localRefreshSec > 10) root.localRefreshSec -= 1
                                }
                            }

                            Rectangle {
                                width: 54; height: 24; radius: 6
                                color:        refreshInput.activeFocus ? (t.cryptoFieldBgFocus) : (t.cryptoFieldBg)
                                border.color: refreshInput.activeFocus ? (t.accent) : "transparent"
                                border.width: 1
                                Behavior on color        { ColorAnimation { duration: 120 } }
                                Behavior on border.color { ColorAnimation { duration: 120 } }

                                TextInput {
                                    id: refreshInput
                                    anchors { fill: parent; leftMargin: 6; rightMargin: 6; topMargin: 4; bottomMargin: 4 }
                                    text:            root.localRefreshSec.toString()
                                    color:           t.cryptoPopupText
                                    font.pixelSize:  12
                                    font.bold:       true
                                    font.family:     "monospace"
                                    selectionColor:  t.accent
                                    horizontalAlignment: TextInput.AlignHCenter
                                    inputMethodHints: Qt.ImhDigitsOnly
                                    validator: IntValidator { bottom: 10; top: 3600 }
                                    clip: true

                                    onActiveFocusChanged: if (!activeFocus) {
                                        const v = parseInt(text)
                                        if (!isNaN(v) && v >= 10 && v <= 3600)
                                            root.localRefreshSec = v
                                        else
                                            text = root.localRefreshSec.toString()
                                    }
                                    onAccepted: {
                                        const v = parseInt(text)
                                        if (!isNaN(v) && v >= 10 && v <= 3600)
                                            root.localRefreshSec = v
                                        else
                                            text = root.localRefreshSec.toString()
                                        focus = false
                                    }

                                    Connections {
                                        target: root
                                        function onLocalRefreshSecChanged() {
                                            if (!refreshInput.activeFocus)
                                                refreshInput.text = root.localRefreshSec.toString()
                                        }
                                    }
                                }
                            }

                            Rectangle {
                                width: 24; height: 24; radius: 7
                                color: incMouse.containsMouse
                                       ? (incMouse.pressed ? (t.accent) : (t.cryptoFieldBgFocus))
                                       : (t.cryptoFieldBg)
                                Behavior on color { ColorAnimation { duration: 100 } }
                                Text { anchors.centerIn: parent; text: "+"; font.pixelSize: 14; font.bold: true; color: t.cryptoPopupText }
                                MouseArea {
                                    id: incMouse
                                    anchors.fill: parent; hoverEnabled: true; cursorShape: Qt.PointingHandCursor
                                    onClicked: if (root.localRefreshSec < 3600) root.localRefreshSec += 1
                                }
                            }
                        }

                        RowLayout {
                            Layout.fillWidth: true

                            Text {
                                text:             "Rotate (seconds)"
                                color:            t.cryptoPopupDim
                                font.pixelSize:   12
                                Layout.fillWidth: true
                            }

                            Rectangle {
                                width: 24; height: 24; radius: 7
                                color: rotDecMouse.containsMouse
                                       ? (rotDecMouse.pressed ? (t.accent) : (t.cryptoFieldBgFocus))
                                       : (t.cryptoFieldBg)
                                Behavior on color { ColorAnimation { duration: 100 } }
                                Text { anchors.centerIn: parent; text: "−"; font.pixelSize: 14; font.bold: true; color: t.cryptoPopupText }
                                MouseArea {
                                    id: rotDecMouse
                                    anchors.fill: parent; hoverEnabled: true; cursorShape: Qt.PointingHandCursor
                                    onClicked: if (root.localRotateSec > 1) root.localRotateSec -= 1
                                }
                            }

                            Rectangle {
                                width: 54; height: 24; radius: 6
                                color:        rotateInput.activeFocus ? (t.cryptoFieldBgFocus) : (t.cryptoFieldBg)
                                border.color: rotateInput.activeFocus ? (t.accent) : "transparent"
                                border.width: 1
                                Behavior on color        { ColorAnimation { duration: 120 } }
                                Behavior on border.color { ColorAnimation { duration: 120 } }

                                TextInput {
                                    id: rotateInput
                                    anchors { fill: parent; leftMargin: 6; rightMargin: 6; topMargin: 4; bottomMargin: 4 }
                                    text:            root.localRotateSec.toString()
                                    color:           t.cryptoPopupText
                                    font.pixelSize:  12
                                    font.bold:       true
                                    font.family:     "monospace"
                                    selectionColor:  t.accent
                                    horizontalAlignment: TextInput.AlignHCenter
                                    inputMethodHints: Qt.ImhDigitsOnly
                                    validator: IntValidator { bottom: 1; top: 600 }
                                    clip: true

                                    onActiveFocusChanged: if (!activeFocus) {
                                        const v = parseInt(text)
                                        if (!isNaN(v) && v >= 1 && v <= 600)
                                            root.localRotateSec = v
                                        else
                                            text = root.localRotateSec.toString()
                                    }
                                    onAccepted: {
                                        const v = parseInt(text)
                                        if (!isNaN(v) && v >= 1 && v <= 600)
                                            root.localRotateSec = v
                                        else
                                            text = root.localRotateSec.toString()
                                        focus = false
                                    }

                                    Connections {
                                        target: root
                                        function onLocalRotateSecChanged() {
                                            if (!rotateInput.activeFocus)
                                                rotateInput.text = root.localRotateSec.toString()
                                        }
                                    }
                                }
                            }

                            Rectangle {
                                width: 24; height: 24; radius: 7
                                color: rotIncMouse.containsMouse
                                       ? (rotIncMouse.pressed ? (t.accent) : (t.cryptoFieldBgFocus))
                                       : (t.cryptoFieldBg)
                                Behavior on color { ColorAnimation { duration: 100 } }
                                Text { anchors.centerIn: parent; text: "+"; font.pixelSize: 14; font.bold: true; color: t.cryptoPopupText }
                                MouseArea {
                                    id: rotIncMouse
                                    anchors.fill: parent; hoverEnabled: true; cursorShape: Qt.PointingHandCursor
                                    onClicked: if (root.localRotateSec < 600) root.localRotateSec += 1
                                }
                            }
                        }

                        ToggleRow {
                            label:   "Show icon on bar"
                            checked: root.localShowIcon
                            onToggled: (v) => root.localShowIcon = v
                        }

                        Rectangle { Layout.fillWidth: true; height: 1; color: t.calSeparator }

                        Rectangle {
                            Layout.fillWidth: true
                            height: 32
                            radius: 9
                            color: applyMouse.containsMouse
                                   ? (applyMouse.pressed
                                      ? Qt.darker(t.accent, 1.15)
                                      : (t.accent))
                                   : (t.cryptoApplyIdleBg)
                            Behavior on color { ColorAnimation { duration: 130 } }

                            Text {
                                anchors.centerIn: parent
                                text:           "Apply & Refresh"
                                color:          applyMouse.containsMouse ? (t.cryptoTextOnAccent) : (t.cryptoPopupText)
                                font.pixelSize: 12
                                font.bold:      true
                                Behavior on color { ColorAnimation { duration: 130 } }
                            }

                            MouseArea {
                                id: applyMouse
                                anchors.fill: parent; hoverEnabled: true; cursorShape: Qt.PointingHandCursor
                                onClicked: {
                                    root.activeCoinIndex = 0
                                    root.persistSettings()
                                    root.fetchPrice()
                                    cryptoPopup.activeTab = 0
                                }
                            }
                        }

                        Item { height: 2 }
                    }
                    }
                }
    }
}
