package pncdsl

import (
	"image/color"

	"github.com/hajimehoshi/ebiten/v2"
	"github.com/hajimehoshi/ebiten/v2/vector"
)

// SpeechBubble renders the line set by the Say action above the speaking
// character (or at FallbackY if the speaker has no on-screen position).
type SpeechBubble struct {
	Name      string
	MaxWidth  int
	Padding   int
	OffsetY   int
	FallbackY int
}

func (s *SpeechBubble) GetName() string { return s.Name }
func (s *SpeechBubble) Tick(ctx *UICtx) {}

func (s *SpeechBubble) Draw(dst *ebiten.Image, ctx *UICtx) {
	g := ctx.Game
	sp := g.speech
	if !sp.Active {
		return
	}
	maxW := s.MaxWidth
	if maxW <= 0 {
		maxW = 200
	}
	pad := s.Padding
	if pad <= 0 {
		pad = 3
	}
	lines := wrapText(sp.Text, maxW)
	w := 0
	for _, ln := range lines {
		if t := textWidth(ln); t > w {
			w = t
		}
	}
	w += pad * 2
	h := len(lines)*16 + pad*2

	// position above speaker if known
	cx, cy := g.Width/2, s.FallbackY
	if cy == 0 {
		cy = 14
	}
	if c, ok := g.runtimeChar(sp.Speaker); ok {
		cx = int(c.pos.X)
		cy = int(c.pos.Y-c.def.H) - s.OffsetY
	}
	x := cx - w/2
	y := cy - h
	if x < 2 {
		x = 2
	}
	if x+w > g.Width-2 {
		x = g.Width - 2 - w
	}
	if y < 2 {
		y = 2
	}

	th := g.Theme()
	vector.DrawFilledRect(dst, float32(x), float32(y), float32(w), float32(h), th.SpeechBubbleBG, false)

	textCol := th.SpeechDefaultText
	if c, ok := g.CharacterManager.Get(sp.Speaker); ok {
		if rgba, ok := c.SpeechColor.(color.RGBA); ok && rgba.A > 0 {
			textCol = rgba
		}
	}
	for i, ln := range lines {
		g.DrawText(dst, ln, x+pad, y+pad+i*16-2, textCol)
	}
}
