package game

import (
	"image"
	"log/slog"
	"openquell/assets"
	"openquell/config"

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

type PlayScene struct {
	Game         *Game
	CurrentLevel int
	Levels       []*Level
	Next         SceneName
	Whoami       SceneName
	UseCache     bool
	MenuRect     image.Rectangle
}

// Implements the actual playing Scene
func NewPlayScene(game *Game, startlevel int) Scene {
	scene := &PlayScene{Whoami: Play, Next: Play, Game: game}

	scene.GenerateLevels(game)
	scene.SetLevel(startlevel)
	scene.MenuRect = image.Rect(config.MenuRectX, config.MenuRectY,
		config.MenuRectX+config.MenuRectCellsize,
		config.MenuRectY+config.MenuRectCellsize)

	return scene
}

func (scene *PlayScene) GenerateLevels(game *Game) {
	min := []int{}
	for _, level := range assets.Project.Levels {
		level := level
		scene.Levels = append(scene.Levels, NewLevel(game, 32, level))
		min = append(min, level.PropertyByIdentifier("minmoves").AsInt())
	}

	scene.Game.Observer.SetupLevelScore(min)
	scene.Game.Observer.SetupMaxLevels(len(min))
	scene.Game.Levels = scene.Levels
}

func (scene *PlayScene) SetLevel(level int) {
	scene.CurrentLevel = level
	scene.Levels[scene.CurrentLevel].SetupGrid(scene.Game)
}

// Interface methods
func (scene *PlayScene) SetNext(next SceneName) {
	scene.Next = next
}

func (scene *PlayScene) GetNext() SceneName {
	// FIXME: set to winner or options screen
	return scene.Next
}

func (scene *PlayScene) ResetNext() {
	scene.Next = scene.Whoami
}

func (scene *PlayScene) Clearscreen() bool {
	return false
}

func (scene *PlayScene) Update() error {
	scene.Levels[scene.CurrentLevel].Update()

	switch {
	case inpututil.IsKeyJustPressed(ebiten.KeyEscape):
		scene.SetNext(Popup)

	case inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft):
		// ok we're checking the menu button here, but drawing it in hud_system,
		// because systems can't switch scenes
		if image.Pt(ebiten.CursorPosition()).In(scene.MenuRect) {
			scene.SetNext(Popup)
		}
	}

	return nil
}

func (scene *PlayScene) Draw(screen *ebiten.Image) {
	// FIXME: why not in Update() ?!?!?!
	if scene.CurrentLevel != scene.Game.Observer.CurrentLevel {
		slog.Debug("level", "current", scene.CurrentLevel,
			"next", scene.Game.Observer.CurrentLevel)
		scene.CurrentLevel = scene.Game.Observer.CurrentLevel
		scene.Levels[scene.CurrentLevel].SetupGrid(scene.Game)
	}

	screen.Clear()
	scene.Levels[scene.CurrentLevel].Draw(screen)
}
