package movement

import (
	"lab.zaar.be/thefish/alchemyst-go/effects"
	"lab.zaar.be/thefish/alchemyst-go/engine/ecs"
	"lab.zaar.be/thefish/alchemyst-go/engine/gamemap"
	"lab.zaar.be/thefish/alchemyst-go/engine/gamestate"
	"lab.zaar.be/thefish/alchemyst-go/engine/mob"
	"lab.zaar.be/thefish/alchemyst-go/engine/types"
)

type Moveable struct {
	Controller *ecs.Controller
	Level      *gamemap.Level
}

func (mov Moveable) Type() string {
	return ecs.MoveableComponent
}

func (mov Moveable) Walk() {

}

// fixme change it to WhatsOnTile
func (mov Moveable) IsBlocked(c types.Coords) bool {
	if mov.Level.GetTile(c).BlocksPass {
		return true
	}
	list := mov.Controller.GetEntitiesWithComponent(ecs.MobComponent)
	for idx := range list {
		coords := mov.Controller.GetComponent(list[idx], ecs.CoordsComponent)
		if coords == nil {
			continue
		}
		coords = coords.(types.Coords)
		if coords != c {
			continue
		}
		m := mov.Controller.GetComponent(list[idx], ecs.MobComponent)
		if m == nil {
			continue
		}
		if m.(mob.Mob).BlocksPass {
			return true
		}
	}
	return false
}

func Walk(entity ecs.Entity, state *gamestate.GameState, dx, dy int) {
	controller := state.Controller
	coords := controller.GetComponent(state.Player, ecs.CoordsComponent).(types.Coords)
	newCoords := types.Coords{X: coords.X + dx, Y: coords.Y + dy}
	if !state.Level.InBounds(newCoords) {
		return
	}
	movable := controller.GetComponent(entity, ecs.MoveableComponent)
	if movable == nil {
		return
	}
	if !movable.(Moveable).IsBlocked(newCoords) ||
		controller.GetComponent(entity, effects.BuffPassWall) != nil {
		controller.UpdateComponent(state.Player, ecs.CoordsComponent, newCoords)
	}

	state.Redraw <- struct{}{}
	state.FovRecompute <- struct{}{}
}
