class_name UndoSystem
extends RefCounted

## UndoSystem - Tracks the last action for undo capability

signal undo_available_changed(available: bool)
signal action_undone(action_name: String)

# Action types that can be undone
enum ActionType {
	NONE,
	DISCARD_FOR_CP,
	DULL_BACKUP_FOR_CP,
	PLAY_CARD
}

# Stored action data for undo
class UndoAction:
	var type: ActionType = ActionType.NONE
	var player_index: int = -1
	var card: CardInstance = null
	var description: String = ""
	# Additional data depending on action type
	var cp_element: Enums.Element = Enums.Element.FIRE
	var cp_amount: int = 0
	var previous_card_state: Enums.CardState = Enums.CardState.ACTIVE
	var from_zone: Enums.ZoneType = Enums.ZoneType.HAND
	var to_zone: Enums.ZoneType = Enums.ZoneType.FIELD_FORWARDS

var last_action: UndoAction = null
var game_state: GameState = null

func _init(state: GameState = null) -> void:
	game_state = state

## Set the game state reference
func set_game_state(state: GameState) -> void:
	game_state = state

## Check if undo is available
func can_undo() -> bool:
	return last_action != null and last_action.type != ActionType.NONE

## Record a discard for CP action
func record_discard_for_cp(player_index: int, card: CardInstance, element: Enums.Element) -> void:
	var action = UndoAction.new()
	action.type = ActionType.DISCARD_FOR_CP
	action.player_index = player_index
	action.card = card
	action.cp_element = element
	action.cp_amount = 2
	action.description = "Discard " + card.get_display_name() + " for CP"

	last_action = action
	undo_available_changed.emit(true)

## Record a dull backup for CP action
func record_dull_backup_for_cp(player_index: int, card: CardInstance, element: Enums.Element) -> void:
	var action = UndoAction.new()
	action.type = ActionType.DULL_BACKUP_FOR_CP
	action.player_index = player_index
	action.card = card
	action.cp_element = element
	action.cp_amount = 1
	action.previous_card_state = Enums.CardState.ACTIVE  # Was active before dulling
	action.description = "Dull " + card.get_display_name() + " for CP"

	last_action = action
	undo_available_changed.emit(true)

## Record playing a card
func record_play_card(player_index: int, card: CardInstance, to_zone: Enums.ZoneType, _cp_spent: Dictionary) -> void:
	var action = UndoAction.new()
	action.type = ActionType.PLAY_CARD
	action.player_index = player_index
	action.card = card
	action.from_zone = Enums.ZoneType.HAND
	action.to_zone = to_zone
	action.description = "Play " + card.get_display_name()

	last_action = action
	undo_available_changed.emit(true)

## Clear the undo history (called when phase changes, combat happens, etc.)
func clear_history() -> void:
	last_action = null
	undo_available_changed.emit(false)

## Execute undo of the last action
func undo() -> bool:
	if not can_undo() or not game_state:
		return false

	var action = last_action
	var success = false

	match action.type:
		ActionType.DISCARD_FOR_CP:
			success = _undo_discard_for_cp(action)
		ActionType.DULL_BACKUP_FOR_CP:
			success = _undo_dull_backup_for_cp(action)
		ActionType.PLAY_CARD:
			success = _undo_play_card(action)

	if success:
		var description = action.description
		last_action = null
		undo_available_changed.emit(false)
		action_undone.emit(description)

	return success

## Undo a discard for CP action
func _undo_discard_for_cp(action: UndoAction) -> bool:
	var player = game_state.get_player(action.player_index)
	if not player:
		return false

	# Remove card from break zone
	if not player.break_zone.has_card(action.card):
		return false

	player.break_zone.remove_card(action.card)

	# Add card back to hand
	player.hand.add_card(action.card)

	# Remove the CP that was generated
	player.cp_pool.add_cp(action.cp_element, -action.cp_amount)

	return true

## Undo a dull backup for CP action
func _undo_dull_backup_for_cp(action: UndoAction) -> bool:
	var player = game_state.get_player(action.player_index)
	if not player:
		return false

	# Check card is still on field
	if not player.field_backups.has_card(action.card):
		return false

	# Reactivate the backup
	action.card.activate()

	# Remove the CP that was generated
	player.cp_pool.add_cp(action.cp_element, -action.cp_amount)

	return true

## Undo playing a card
func _undo_play_card(action: UndoAction) -> bool:
	var player = game_state.get_player(action.player_index)
	if not player:
		return false

	var card = action.card

	# Remove from field
	var removed = false
	if action.to_zone == Enums.ZoneType.FIELD_FORWARDS:
		if player.field_forwards.has_card(card):
			player.field_forwards.remove_card(card)
			removed = true
	elif action.to_zone == Enums.ZoneType.FIELD_BACKUPS:
		if player.field_backups.has_card(card):
			player.field_backups.remove_card(card)
			removed = true

	if not removed:
		return false

	# Return to hand
	player.hand.add_card(card)

	# Reset card state
	card.state = Enums.CardState.ACTIVE
	card.turns_on_field = 0

	# Refund the CP (we don't track exact CP spent, so this is simplified)
	# In a full implementation, we'd track what CP was spent
	# For now, we'll add back CP equal to the card cost
	var cost = card.card_data.cost
	var element = card.get_element()
	player.cp_pool.add_cp(element, cost)

	return true

## Get description of the last action (for display)
func get_last_action_description() -> String:
	if not can_undo():
		return ""
	return last_action.description
