class_name MineProvider extends WorkProvider
## WorkProvider for the "mine" work category.
##
## Scans World.rocks for the nearest mineable Rock (Manhattan distance from
## the requesting pawn) and returns a two-toil Job:
##   walk_to(rock.tile) → interact(rock.get_path(), "on_mine_tick")
##
## The INTERACT toil calls Rock.on_mine_tick() once per sim tick; the Rock
## internally tracks mine_progress and handles removal when MINE_TICKS is
## reached.  The toil finishes automatically when is_mineable() returns
## false (exhausted) or when the node is freed.
##
## Phase 4 simplification: rocks are assumed walkable during mining approach
## (they may block movement in a later phase once obstruction is added to the
## pathfinder).
##
## Duck-typing note: Rock is referenced without class_name (class may not be
## registered yet when this provider loads).  World.rocks may also hold BigRock
## instances; both expose the same interface so we just iterate the array:
##   rock.tile: Vector2i                              — for distance scoring
##   rock.is_mineable() -> bool
##   rock.approach_tile_for(pawn_tile) -> Vector2i    — walk destination
##   rock.get_path() -> NodePath


func _init() -> void:
	category = &"mine"
	priority = 4  # Slightly lower than chop (5); both higher than rest (0).


## Returns a Job targeting the nearest mineable Rock, or null if none exists.
## `pawn` is duck-typed: must expose .tile (Vector2i).
func find_best_for(pawn) -> Job:
	var best = null
	var best_dist: int = 999999

	for rock in World.rocks:
		if not rock.is_mineable():
			continue
		# Gate on player designation — pawns don't auto-mine undesignated rocks.
		# Boot seed in world.gd auto-designates SAMPLE_ROCKS so the demo still runs.
		if not rock.mine_designated:
			continue
		if Job.is_target_taken_by_other(rock, pawn):
			continue
		var d: int = abs(rock.tile.x - pawn.tile.x) + abs(rock.tile.y - pawn.tile.y)
		if d < best_dist:
			best_dist = d
			best = rock

	if best == null:
		return null

	var j := Job.new()
	j.label = "Mine rock at %s" % best.tile
	j.target_node = best
	# Ask the entity where the pawn should stand. Single rocks return their own
	# tile (walkable). BigRocks return a perimeter tile so the pawn doesn't try
	# to pathfind into the blocked 2×2 footprint.
	var walk_tile: Vector2i = (
		best.approach_tile_for(pawn.tile) if best.has_method("approach_tile_for") else best.tile
	)
	j.toils.append(Toil.walk_to(walk_tile))
	j.toils.append(Toil.interact(best.get_path(), &"on_mine_tick"))
	return j
