import QtQuick
import QtQuick.Controls
import QtQuick.Controls.impl
import QtQuick.Layouts
import ISC

// Curve overlay chart card with the alignment timeline scrubber.
PanelBox {
    id: card

    required property var trendDataA
    required property var trendDataB
    required property int seriesLen
    required property bool hasSeries
    required property bool comparing

    // Scrubber position — the internal Slider is private; consumers
    // read/write frameIndex and call focusScrubber().
    property alias frameIndex: scrubber.value

    function focusScrubber() { scrubber.forceActiveFocus() }

    implicitHeight: chartCol.implicitHeight + 24

    ColumnLayout {
        id: chartCol
        anchors.fill: parent
        anchors.margins: 12
        spacing: 8

        RowLayout {
            Layout.fillWidth: true
            SectionTitle {
                text: "CURVE OVERLAY"
                Layout.fillWidth: true
            }
            Row {
                spacing: 16
                visible: card.hasSeries
                Row {
                    spacing: 4
                    Rectangle { width: 12; height: 3; radius: 1.5; color: Theme.primaryAccent; anchors.verticalCenter: parent.verticalCenter }
                    Label { text: "Run A"; font.pixelSize: Theme.fontXs; color: Theme.bodyColor }

                }
                Row {
                    spacing: 4
                    Rectangle { width: 12; height: 3; radius: 1.5; color: Theme.themeSkill; anchors.verticalCenter: parent.verticalCenter }
                    Label { text: "Run B"; font.pixelSize: Theme.fontXs; color: Theme.bodyColor }
                }
            }
        }

        Rectangle {
            Layout.fillWidth: true
            Layout.preferredHeight: 200
            color: Theme.fieldBackground
            border.color: Theme.cardBorder
            border.width: 1
            radius: Theme.radiusSm
            clip: true

            Canvas {
                id: overlayCanvas
                anchors.fill: parent
                visible: card.hasSeries

                readonly property real padLeft: 50
                readonly property real padRight: 16
                readonly property real padTop: 24
                readonly property real padBottom: 36

                // Nice tick step (1/2/5 × 10^k) — same scheme as TrendChartItem,
                // so labels land on round numbers instead of raw data min/max.
                function niceStep(rawStep) {
                    var mag = Math.pow(10, Math.floor(Math.log10(rawStep)))
                    return [1, 2, 5, 10].map(function (s) { return s * mag })
                                        .find(function (s) { return s >= rawStep })
                }

                function drawGrid(ctx, minV, maxV, yStep, dataLen) {
                    var plotW = width - padLeft - padRight
                    var plotH = height - padTop - padBottom
                    var range = (maxV - minV) || 1

                    ctx.strokeStyle = Theme.chartGridLine
                    ctx.lineWidth = 1
                    ctx.fillStyle = Theme.chartAxisText
                    ctx.font = "10px " + Theme.uiFontFamily
                    ctx.textAlign = "right"

                    var ySteps = Math.max(1, Math.round(range / yStep))
                    var yDec = Math.max(0, -Math.floor(Math.log10(yStep)))
                    for (var yi = 0; yi <= ySteps; yi++) {
                        var yFrac = yi / ySteps
                        var yPx = padTop + plotH * yFrac
                        var yVal = maxV - yFrac * range

                        ctx.beginPath()
                        ctx.moveTo(padLeft, yPx)
                        ctx.lineTo(padLeft + plotW, yPx)
                        ctx.stroke()

                        ctx.fillText(yVal.toFixed(yDec), padLeft - 6, yPx + 3)
                    }

                    ctx.textAlign = "center"
                    var xMax = dataLen - 1
                    if (xMax > 0) {
                        var xStep = niceStep(xMax / 5 || 1)
                        for (var xIdx = 0; xIdx <= xMax; xIdx += xStep) {
                            var xPx = padLeft + (xIdx / xMax) * plotW
                            ctx.fillText(xIdx.toString(), xPx, height - 20)
                        }
                    }

                    ctx.save()
                    ctx.translate(14, padTop + plotH / 2)
                    ctx.rotate(-Math.PI / 2)
                    ctx.textAlign = "center"
                    ctx.font = "12px " + Theme.uiFontFamily
                    ctx.fillText("Celcius (°C)", 0, 0)
                    ctx.restore()

                    ctx.textAlign = "center"
                    ctx.font = "12px " + Theme.uiFontFamily
                    ctx.fillText("Frame", padLeft + plotW / 2, height - 4)
                }

                function drawSeries(ctx, series, minV, range, color, dataLen) {
                    // x is mapped against the shared frame domain (dataLen), not the
                    // series' own length — otherwise a shorter run's line stretches to
                    // fill the whole plot instead of stopping where its data ends.
                    if (series.length < 2) return
                    var plotW = width - padLeft - padRight
                    var plotH = height - padTop - padBottom

                    ctx.strokeStyle = color
                    ctx.lineWidth = 2
                    ctx.beginPath()
                    for (var i = 0; i < series.length; i++) {
                        var x = padLeft + (i / (dataLen - 1)) * plotW
                        var y = padTop + plotH - ((series[i] - minV) / range) * plotH
                        if (i === 0) ctx.moveTo(x, y)
                        else ctx.lineTo(x, y)
                    }
                    ctx.stroke()
                }

                function drawScrubMarker(ctx) {
                    if (card.seriesLen < 2) return
                    var plotW = width - padLeft - padRight
                    var x = padLeft + (scrubber.value / (card.seriesLen - 1)) * plotW
                    ctx.strokeStyle = Theme.primaryAccent
                    ctx.lineWidth = 1.5
                    ctx.setLineDash([3, 3])
                    ctx.beginPath()
                    ctx.moveTo(x, padTop)
                    ctx.lineTo(x, height - padBottom)
                    ctx.stroke()
                    ctx.setLineDash([])
                }

                onPaint: {
                    var ctx = getContext("2d")
                    ctx.reset()
                    if (!card.hasSeries) return
                    var all = card.trendDataA.concat(card.trendDataB)
                    var minV = Math.min.apply(null, all)
                    var maxV = Math.max.apply(null, all)
                    var padding = (maxV - minV) * 0.05
                    minV -= padding
                    maxV += padding
                    // Snap bounds to nice-step multiples -> stable round-number axis
                    var yStep = niceStep((maxV - minV) / 5 || 1)
                    minV = Math.floor(minV / yStep) * yStep
                    maxV = Math.ceil(maxV / yStep) * yStep
                    var range = (maxV - minV) || 1

                    drawGrid(ctx, minV, maxV, yStep, card.seriesLen)
                    drawSeries(ctx, card.trendDataA, minV, range, Theme.primaryAccent, card.seriesLen)
                    drawSeries(ctx, card.trendDataB, minV, range, Theme.themeSkill, card.seriesLen)
                    drawScrubMarker(ctx)
                }

                Connections {
                    target: card
                    function onTrendDataAChanged() { overlayCanvas.requestPaint() }
                    function onTrendDataBChanged() { overlayCanvas.requestPaint() }
                }
                Connections {
                    target: scrubber
                    function onValueChanged() { overlayCanvas.requestPaint() }
                }
            }

            // Empty state
            ColumnLayout {
                anchors.centerIn: parent
                visible: !card.hasSeries
                spacing: 8

                IconImage {
                    Layout.alignment: Qt.AlignHCenter
                    visible: !card.comparing
                    source: "../icons/bar-chart.svg"
                    width: 32; height: 32
                    sourceSize.width: 32
                    sourceSize.height: 32
                    color: Theme.sideMutedText
                }
                Label {
                    Layout.alignment: Qt.AlignHCenter
                    text: card.comparing ? "Running DTW comparison…" : "Select two runs and run comparison"
                    color: Theme.bodyColor
                    font.pixelSize: Theme.fontSm
                }
                Label {
                    Layout.alignment: Qt.AlignHCenter
                    visible: !card.comparing
                    text: "Click a run box on the right, then select a file from the left panel."
                    color: Theme.sideMutedText
                    font.pixelSize: Theme.fontXs
                }
            }
        }

        // ── Alignment Timeline Scrubber ────────────
        ColumnLayout {
            Layout.fillWidth: true
            spacing: 4
            visible: card.hasSeries

            Rectangle {
                Layout.fillWidth: true
                height: 1
                color: Theme.cardBorder
            }

            SectionTitle {
                text: "TIMELINE SCRUBBER"
                Layout.fillWidth: true
                Layout.topMargin: 8
            }

            Slider {
                id: scrubber
                Layout.fillWidth: true
                leftPadding: overlayCanvas.padLeft
                rightPadding: overlayCanvas.padRight
                from: 0
                to: Math.max(1, card.seriesLen - 1)
                stepSize: 1
                value: 0
            }


        }
    }
}
