extends Node2D

const GRID_SIZE := Vector2i(8, 8)
const TILE_TYPES := 5
const TILE_SCENE := preload("res://scenes/match3/tile.tscn")

var grid := []

func _ready():
	_initialize_grid()

func _initialize_grid():
	for y in range(GRID_SIZE.y):
		grid.append([])
		for x in range(GRID_SIZE.x):
			var tile = TILE_SCENE.instantiate()
			tile.position = Vector2(x, y) * 64  # Adjust to your tile size
			tile.grid_position = Vector2i(x, y)
			tile.tile_type = randi() % TILE_TYPES
			add_child(tile)
			grid[y].append(tile)

func _has_match_at(pos: Vector2i) -> bool:
	var matches_horizontal = _get_match_line(pos, Vector2i(1, 0))
	if matches_horizontal.size() >= 3:
		return true

	var matches_vertical = _get_match_line(pos, Vector2i(0, 1))
	return matches_vertical.size() >= 3

func _get_match_line(start: Vector2i, dir: Vector2i) -> Array:
	var line = [grid[start.y][start.x]]
	var type = grid[start.y][start.x].tile_type

	for offset in [1, -1]:
		var current = start + dir * offset
		while current.x >= 0 and current.y >= 0 and current.x < GRID_SIZE.x and current.y < GRID_SIZE.y:
			var neighbor = grid[current.y][current.x]
			if neighbor.tile_type != type:
				break
			line.append(neighbor)
			current += dir * offset

	return line

func _clear_matches():
	var to_clear := []

	for y in range(GRID_SIZE.y):
		for x in range(GRID_SIZE.x):
			var pos = Vector2i(x, y)
			var horiz = _get_match_line(pos, Vector2i(1, 0))
			if horiz.size() >= 3:
				to_clear.append_array(horiz)
			var vert = _get_match_line(pos, Vector2i(0, 1))
			if vert.size() >= 3:
				to_clear.append_array(vert)

	# Remove duplicates using dictionary keys trick
	var unique_dict := {}
	for tile in to_clear:
		unique_dict[tile] = true
	to_clear = unique_dict.keys()

	for tile in to_clear:
		grid[tile.grid_position.y][tile.grid_position.x] = null
		tile.queue_free()

	_drop_tiles()
	await get_tree().create_timer(0.2).timeout
	_fill_empty_cells()

func _drop_tiles():
	var moved = true
	while moved:
		moved = false
		for x in range(GRID_SIZE.x):
			for y in range(GRID_SIZE.y - 2, -1, -1):
				var tile = grid[y][x]
				if tile and not grid[y + 1][x]:
					grid[y + 1][x] = tile
					grid[y][x] = null
					tile.grid_position = Vector2i(x, y + 1)
					# You can animate position here using Tween for smooth drop:
					# tween.interpolate_property(tile, "position", tile.position, Vector2(x, y + 1) * 64, 0.2)
					tile.position = Vector2(x, y + 1) * 64
					moved = true

func _fill_empty_cells():
	for y in range(GRID_SIZE.y):
		for x in range(GRID_SIZE.x):
			if not grid[y][x]:
				var tile = TILE_SCENE.instantiate()
				tile.grid_position = Vector2i(x, y)
				tile.tile_type = randi() % TILE_TYPES
				tile.position = Vector2(x, y) * 64
				grid[y][x] = tile
				add_child(tile)

	# Recheck matches
	await get_tree().create_timer(0.1).timeout
	_clear_matches()
