package ui

import "strings"

// renderWave draws a Braille-character oscilloscope waveform from raw audio samples.
// Each Braille character covers a 2×4 dot grid, giving smooth sub-cell resolution.
func (v *Visualizer) renderWave() string {
	height := v.Rows
	charCols := PanelWidth
	dotRows := height * 4
	dotCols := charCols * 2

	samples := v.waveBuf
	n := len(samples)

	// Downsample audio to one y-position per horizontal dot column.
	if cap(v.waveYBuf) >= dotCols {
		v.waveYBuf = v.waveYBuf[:dotCols]
	} else {
		v.waveYBuf = make([]int, dotCols)
	}
	ypos := v.waveYBuf
	for x := range dotCols {
		var sample float64
		if n > 0 {
			idx := x * n / dotCols
			if idx >= n {
				idx = n - 1
			}
			sample = samples[idx]
		}
		// Map sample [-1, 1] to dot row [0, dotRows-1]; center is dotRows/2.
		y := int((1.0 - sample) * float64(dotRows-1) / 2.0)
		ypos[x] = max(0, min(dotRows-1, y))
	}

	lines := make([]string, height)
	for row := range height {
		var content strings.Builder
		dotRowStart := row * 4

		for ch := range charCols {
			var braille rune = '\u2800'
			dotColStart := ch * 2

			for dc := range 2 {
				x := dotColStart + dc
				y := ypos[x]

				// Connect to previous point so the waveform is continuous.
				prevY := y
				if x > 0 {
					prevY = ypos[x-1]
				}
				yMin := min(y, prevY)
				yMax := max(y, prevY)

				for dr := range 4 {
					dotY := dotRowStart + dr
					if dotY >= yMin && dotY <= yMax {
						braille |= brailleBit[dr][dc]
					}
				}
			}

			content.WriteRune(braille)
		}
		lines[row] = specWrap(float64(height-1-row)/float64(height), content.String())
	}

	return strings.Join(lines, "\n")
}
