package systems

import (
	"fmt"
	"image/color"
	"openquell/assets"
	"openquell/config"
	"openquell/observers"
	"strings"

	"github.com/hajimehoshi/ebiten/v2"
	"github.com/mlange-42/arche/ecs"
	"github.com/solarlune/ldtkgo"
)

const MaxLetters int = 52

type HudSystem struct {
	World    *ecs.World
	Cellsize int
	Observer *observers.GameObserver
	Plan     *ldtkgo.Level
	MenuIcon *ebiten.Image
}

func NewHudSystem(world *ecs.World, plan *ldtkgo.Level) System {
	system := &HudSystem{
		Observer: observers.GetGameObserver(world),
		World:    world,
		Plan:     plan,
		MenuIcon: assets.Assets["menu"],
	}

	return system
}

func (system *HudSystem) Update() error {
	return nil
}

func (system *HudSystem) Draw(screen *ebiten.Image) {
	op := &ebiten.DrawImageOptions{}
	screen.DrawImage(assets.Assets["hud"], op)
	/*
		ebitenutil.DebugPrintAt(screen, fmt.Sprintf(
			"FPS: %02.f  TPS: %02.f      Level %s: %s",
			ebiten.ActualFPS(),
			ebiten.ActualTPS(),
			system.Plan.Name,
			system.Plan.Description,
		), 10, 10)
	*/

	score := fmt.Sprintf("Score: %d", system.Observer.GetScore())
	level := fmt.Sprintf("Level %d: %s", system.Plan.PropertyByIdentifier("level").AsInt(),
		strings.ReplaceAll(system.Plan.Identifier, "_", " "))
	des := system.Plan.PropertyByIdentifier("description").AsString()

	assets.FontRenderer.Renderer.SetSizePx(20)
	assets.FontRenderer.Renderer.SetTarget(screen)

	// FIXME: do not use hard coded values for HUD
	system.Print(score, 450, 22)
	x := system.GetTextXCentered(des)

	system.Print(des, x, 374)
	system.Print(level, 10, 22)

	op.GeoM.Reset()
	op.GeoM.Translate(600, 0)
	screen.DrawImage(system.MenuIcon, op)
}

func (system *HudSystem) Print(text string, x, y int) {
	fg := &config.FontColorFG
	bg := &color.RGBA{0x9a, 0x6f, 0xff, 255}

	assets.FontRenderer.Renderer.SetColor(bg)
	assets.FontRenderer.Renderer.Draw(text, x, y)
	assets.FontRenderer.Renderer.SetColor(fg)
	assets.FontRenderer.Renderer.Draw(text, x-1, y-1)
}

func (system *HudSystem) GetTextXCentered(text string) int {
	size := len(text)
	lettersize := system.Observer.Width / MaxLetters
	descsize := lettersize * size
	return system.Observer.Width/2 - descsize/2
}
