//go:build !(js && wasm)

package app

import (
	"strconv"
	"time"

	. "kjol/wasmruntime/vdom"
	ui "kjol/webui"
)

// ServerCounter is a SERVER component — note it's written exactly like a client
// component (same builders, signals, On handlers). The //gowasm:server directive
// makes the build generate a client stub so calling ServerCounter() on the
// frontend is identical to calling any component; the state and this render run
// on the server (its chart SVG is drawn there by webui.ChartSVG), and clicks
// round-trip over /rsc.
//
// The chart plots the counter value against the wall-clock time of each click
// (milliseconds since the first click), so spacing clicks out spreads the data
// points along the x-axis. Because the component is stateless on the server, the
// click points live in a signal that round-trips with the rest of its state
// (a plain slice would reset on every request).
//
//gowasm:server
func ServerCounter() func() *VNode {
	count := NewSignal(0)
	points := NewSignal([]clickPoint{})
	bump := func(delta int) {
		count.Set(count.Get() + delta)
		points.Set(append(points.Get(), clickPoint{T: time.Now().UnixMilli(), V: count.Get()}))
	}
	// No card of its own: the component draws bare content and lets the caller frame it.
	// The docs page already puts it in a demo panel, and a card inside a card gives you
	// two borders and two shadows around the same thing.
	return func() *VNode {
		return Div(
			Div(Attr("class", "flex items-center gap-2 mb-3"),
				Span(Attr("class", "text-ink-soft"), Text("Server counter: ")),
				Strong(Attr("class", "badge inline-flex items-center rounded-full bg-green-700 px-2.5 py-0.5 text-sm font-semibold text-white"), Text(strconv.Itoa(count.Get()))),
				Div(Attr("class", "ml-auto flex gap-1"),
					ui.Button(ui.ButtonProps{Color: ui.ButtonSecondary, Small: true, Text: "−", OnClick: func() { bump(-1) }}),
					ui.Button(ui.ButtonProps{Color: ui.ButtonGreen, Small: true, Text: "+", OnClick: func() { bump(1) }}),
				),
			),
			Div(Attr("class", "rounded-default border border-line bg-surface p-2 overflow-auto"),
				Raw(clickChartSVG(points.Get()))),
		)
	}
}

// clickPoint records one click: its wall-clock time and the resulting counter
// value. Exported fields so the signal's JSON snapshot round-trips it.
type clickPoint struct {
	T int64 // click time, Unix milliseconds
	V int   // counter value after the click
}

// clickChartSVG plots the counter value at each click as a line, drawn on the server by
// webui.ChartSVG — the same chart geometry the client kit uses, rendered to a static SVG
// string (no controller, no hover) because a server component's output is HTML.
func clickChartSVG(points []clickPoint) string {
	if len(points) == 0 {
		return `<span class="text-ink-muted">Click + / − to plot the counter over each click.</span>`
	}
	vals := make([]float64, len(points))
	labels := make([]string, len(points))
	for i, p := range points {
		vals[i] = float64(p.V)
		labels[i] = strconv.Itoa(i + 1)
	}
	return ui.ChartSVG(ui.ChartProps{
		Kind:      ui.ChartLine,
		Labels:    labels,
		Series:    []ui.ChartSeries{{Name: "Counter", Data: vals, Color: "var(--color-chart-4)"}},
		Height:    240,
		NoTooltip: true,
	})
}
