package webui

import "kjol/wasmruntime/vdom"

// Port of web/kit/ToggleSwitch.tsx. Reactive accessors collapse to plain values.

// ToggleSwitch renders an on/off <button role="switch"> with an optional label
// and description. onChange receives the next checked state.
func ToggleSwitch(checked bool, onChange func(bool), label, description string, disabled bool, class string) *vdom.VNode {
	toggle := func() {
		if disabled {
			return
		}
		onChange(!checked)
	}

	trackState := "bg-surface-strong"
	if checked {
		trackState = "bg-primary"
	}
	trackCls := cx("relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors focus-visible:outline-2 focus-visible:outline-primary focus-visible:outline-offset-2 disabled:cursor-not-allowed disabled:opacity-50", trackState)

	knobState := "translate-x-0.5"
	if checked {
		knobState = "translate-x-[18px]"
	}
	knobCls := cx("inline-block h-4 w-4 transform rounded-full bg-surface shadow-sm transition-transform", knobState)

	ariaChecked := "false"
	if checked {
		ariaChecked = "true"
	}
	btnMods := []vdom.Mod{
		vdom.Attr("type", "button"),
		vdom.Attr("role", "switch"),
		vdom.Attr("aria-checked", ariaChecked),
		vdom.Attr("class", trackCls),
		vdom.On(vdom.EVENT_CLICK, toggle),
		vdom.Span(vdom.Attr("class", knobCls)),
	}
	if disabled {
		btnMods = append(btnMods, vdom.Attr("disabled", "disabled"))
	}

	mods := []vdom.Mod{vdom.Attr("class", cx("flex items-center gap-2", class)), vdom.Button(btnMods...)}

	if label != "" || description != "" {
		text := []vdom.Mod{vdom.Attr("class", "flex flex-col leading-tight")}
		if label != "" {
			labelColor := "text-ink"
			if disabled {
				labelColor = "text-ink-faint"
			}
			text = append(text, vdom.Span(vdom.Attr("class", cx("text-sm select-none", labelColor)),
				vdom.On(vdom.EVENT_CLICK, toggle),
				vdom.Text(label)))
		}
		if description != "" {
			text = append(text, vdom.Span(vdom.Attr("class", "text-ss text-ink-muted"), vdom.Text(description)))
		}
		mods = append(mods, vdom.Div(text...))
	}
	return vdom.Div(mods...)
}
