/* components/MatrixCanvas.jsx */
(() => {
    const { AxisLine, PlotThumb } = window.Cmp;

    function MatrixCanvas(props) {
        const {
            expanded,
            theme,
            exporting,
            items,
            xMetric,
            yMetric,
            xDef,
            yDef,
            targetCTR,
            targetCVR,
            hideNoCV,
            toX,
            toY,
            sX,
            sY,
            getMetricValue,
            canvasOuterRef,
            canvasInnerRef,
            onWheel,
            onPointerDown,
            onTouchStart,
            onTouchMove,
            onTouchEnd,
            pan,
            zoom,
            zoomAt,
            resetView,
            exportPNG,
            setExpanded,
            sxKnob,
            syKnob,
            setSxKnob,
            setSyKnob,
            onItemClick,
        } = props;

        const isFiniteNum = (v) => v != null && Number.isFinite(Number(v));
        const xLabel = xDef?.label || "X";
        const yLabel = yDef?.label || "Y";
        const xUnit = xDef?.isPercent ? "%" : xDef?.unit || "";
        const yUnit = yDef?.isPercent ? "%" : yDef?.unit || "";

        // 端固定ラベル（基準線に追従：panも加味）
        const fixedLabels = (() => {
            const out = [];

            if (isFiniteNum(targetCTR)) {
                const pos = toX(Number(targetCTR)) * sX;
                out.push(
                    <div
                        key="v"
                        className="absolute z-[65] px-2 py-1 rounded-full text-[12px] leading-none whitespace-nowrap select-none pointer-events-none"
                        style={{
                            left: `calc(${pos}% + ${pan.x}px)`,
                            top: "8px",
                            transform: "translateX(-50%)",
                            background: "rgba(0,0,0,0.55)",
                            color: "rgba(255,255,255,0.92)",
                            border: "1px solid rgba(255,255,255,0.12)",
                            backdropFilter: "blur(6px)",
                            WebkitBackdropFilter: "blur(6px)",
                        }}
                    >
                        {xLabel}：{window.Num.fmt(Number(targetCTR))}
                        {xUnit}
                    </div>
                );
            }
            if (isFiniteNum(targetCVR)) {
                const pos = toY(Number(targetCVR)) * sY;
                out.push(
                    <div
                        key="h"
                        className="absolute z-[65] px-2 py-1 rounded-full text-[12px] leading-none whitespace-nowrap select-none pointer-events-none"
                        style={{
                            left: "8px",
                            top: `calc(${pos}% + ${pan.y}px)`,
                            transform: "translateY(-50%)",
                            background: "rgba(0,0,0,0.55)",
                            color: "rgba(255,255,255,0.92)",
                            border: "1px solid rgba(255,255,255,0.12)",
                            backdropFilter: "blur(6px)",
                            WebkitBackdropFilter: "blur(6px)",
                        }}
                    >
                        {yLabel}：{window.Num.fmt(Number(targetCVR))}
                        {yUnit}
                    </div>
                );
            }
            return out;
        })();

        const CanvasBody = (
            <div
                ref={canvasOuterRef}
                className={
                    expanded
                        ? "relative w-full flex-1 rounded-2xl border border-neutral-700/50 overflow-hidden bg-neutral-900"
                        : "relative w-full h-[62vh] rounded-2xl border border-neutral-700/50 overflow-hidden bg-neutral-900"
                }
                style={{ touchAction: "none" }}
                onWheel={onWheel}
                onPointerDown={onPointerDown}
                onTouchStart={onTouchStart}
                onTouchMove={onTouchMove}
                onTouchEnd={onTouchEnd}
            >
                {/* 端固定の基準線ラベル（canvas外層に固定） */}
                {fixedLabels}

                <div
                    ref={canvasInnerRef}
                    className="absolute inset-0"
                    style={{
                        transform: `translate3d(${pan.x}px, ${pan.y}px, 0)`,
                        transformOrigin: "center center",
                        willChange: "transform",
                    }}
                >
                    {/* 基準線（線自体はキャンバスに追従） */}
                    {isFiniteNum(targetCTR) ? (
                        <AxisLine
                            orientation="vertical"
                            pos={toX(Number(targetCTR))}
                            scaleX={sX}
                        />
                    ) : null}
                    {isFiniteNum(targetCVR) ? (
                        <AxisLine
                            orientation="horizontal"
                            pos={toY(Number(targetCVR))}
                            scaleY={sY}
                        />
                    ) : null}

                    {items.map((it) => {
                        const xVal = getMetricValue(xMetric, it);
                        const yVal = getMetricValue(yMetric, it);
                        if (xVal == null || yVal == null) return null;
                        if (hideNoCV && (!it.cvCount || it.cvCount <= 0))
                            return null;

                        const x = toX(xVal);
                        const y = toY(yVal);
                        const inside =
                            Number.isFinite(x) &&
                            Number.isFinite(y) &&
                            x >= 0 &&
                            x <= 100 &&
                            y >= 0 &&
                            y <= 100;
                        if (!inside) return null;

                        return (
                            <PlotThumb
                                key={it.id}
                                x={x}
                                y={y}
                                item={it}
                                theme={theme}
                                scaleX={sX}
                                scaleY={sY}
                                onClick={onItemClick}
                            />
                        );
                    })}
                </div>

                {/* 右下：コントローラ（X/Yスケール + 全体縮尺） */}
                <div
                    className="absolute right-3 bottom-3 z-[70] flex items-end gap-2 select-none pointer-events-auto"
                    data-noprint="1"
                    style={{ visibility: exporting ? "hidden" : "visible" }}
                    onPointerDown={(e) => e.stopPropagation()}
                    onMouseDown={(e) => e.stopPropagation()}
                >
                    {/* X/Y スケール（密度） */}
                    <div className="hidden md:flex flex-col gap-1 bg-black/50 text-white rounded-xl px-2 py-2 backdrop-blur-sm border border-white/10">
                        <div className="flex items-center gap-2">
                            <div className="text-[11px] opacity-70 whitespace-nowrap w-7">
                                X軸
                            </div>
                            <input
                                type="range"
                                min={-6}
                                max={6}
                                step={0.25}
                                value={sxKnob}
                                onChange={(e) =>
                                    setSxKnob &&
                                    setSxKnob(Number(e.target.value))
                                }
                                style={{ width: "140px" }}
                            />
                        </div>
                        <div className="flex items-center gap-2">
                            <div className="text-[11px] opacity-70 whitespace-nowrap w-7">
                                Y軸
                            </div>
                            <input
                                type="range"
                                min={-6}
                                max={6}
                                step={0.25}
                                value={syKnob}
                                onChange={(e) =>
                                    setSyKnob &&
                                    setSyKnob(Number(e.target.value))
                                }
                                style={{ width: "140px" }}
                            />
                        </div>
                    </div>

                    {/* 全体縮尺（ズーム） */}
                    <div className="flex items-center gap-2 bg-black/50 text-white rounded-xl px-2 py-1 backdrop-blur-sm border border-white/10">
                        <button
                            type="button"
                            className="w-7 h-7 rounded-lg bg-white/10 hover:bg-white/20 flex items-center justify-center"
                            onClick={() => {
                                const rect =
                                    canvasOuterRef.current?.getBoundingClientRect();
                                if (!rect) return;
                                zoomAt(
                                    rect.left + rect.width / 2,
                                    rect.top + rect.height / 2,
                                    zoom - 0.1
                                );
                            }}
                            aria-label="zoom out"
                        >
                            −
                        </button>

                        <div className="text-xs w-14 text-center tabular-nums">
                            {Math.round(zoom * 100)}%
                        </div>

                        <button
                            type="button"
                            className="w-7 h-7 rounded-lg bg-white/10 hover:bg-white/20 flex items-center justify-center"
                            onClick={() => {
                                const rect =
                                    canvasOuterRef.current?.getBoundingClientRect();
                                if (!rect) return;
                                zoomAt(
                                    rect.left + rect.width / 2,
                                    rect.top + rect.height / 2,
                                    zoom + 0.1
                                );
                            }}
                            aria-label="zoom in"
                        >
                            ＋
                        </button>

                        <button
                            type="button"
                            className="ml-1 px-2 h-7 rounded-lg bg-white/10 hover:bg-white/20 text-xs"
                            onClick={resetView}
                            aria-label="reset view"
                        >
                            リセット
                        </button>
                    </div>
                </div>
            </div>
        );

        if (!expanded) return CanvasBody;

        return (
            <div
                className="fixed inset-0 z-[90] bg-black/80 backdrop-blur-sm p-4 flex flex-col"
                style={{ overscrollBehavior: "none" }}
            >
                <div className="flex items-center justify-between mb-3">
                    <div className="text-sm opacity-80">全画面表示</div>
                    <div className="flex items-center gap-2">
                        <button
                            type="button"
                            onClick={() => setExpanded(false)}
                            className="px-3 py-2 rounded-md bg-neutral-800 text-white hover:bg-neutral-700 text-sm"
                            title="通常表示に戻す"
                        >
                            ⤡ 通常表示
                        </button>
                        <button
                            type="button"
                            onClick={exportPNG}
                            className="px-3 py-2 rounded-md bg-emerald-600 text-white hover:bg-emerald-500 text-sm"
                            title="画像として保存"
                        >
                            画像を保存
                        </button>
                    </div>
                </div>

                {CanvasBody}

                <div className="mt-2 text-xs opacity-60">
                    ヒント：ホイールで拡大縮小、ドラッグで移動。スマホは2本指でピンチ。
                </div>
            </div>
        );
    }

    window.Cmp = window.Cmp || {};
    window.Cmp.MatrixCanvas = MatrixCanvas;
})();
