class_name Player
extends RefCounted

## Player - Represents a player's game state

var player_index: int = 0
var player_name: String = "Player"

# Zones
var deck: Zone
var hand: Zone
var field_forwards: Zone
var field_backups: Zone
var damage_zone: Zone
var break_zone: Zone

# Resources
var cp_pool: CPPool

# Game state
var is_first_player: bool = false
var has_mulliganed: bool = false

# Constants
const MAX_HAND_SIZE: int = 5
const MAX_BACKUPS: int = 5
const DAMAGE_TO_LOSE: int = 7

func _init(index: int, name: String = "") -> void:
	player_index = index
	player_name = name if name != "" else "Player %d" % (index + 1)

	# Initialize zones
	deck = Zone.new(Enums.ZoneType.DECK, index)
	hand = Zone.new(Enums.ZoneType.HAND, index)
	field_forwards = Zone.new(Enums.ZoneType.FIELD_FORWARDS, index)
	field_backups = Zone.new(Enums.ZoneType.FIELD_BACKUPS, index)
	damage_zone = Zone.new(Enums.ZoneType.DAMAGE, index)
	break_zone = Zone.new(Enums.ZoneType.BREAK, index)

	# Initialize CP pool
	cp_pool = CPPool.new()

## Setup the player's deck from a list of card IDs
func setup_deck(card_ids: Array[String]) -> void:
	for card_id in card_ids:
		var card_data = CardDatabase.get_card(card_id)
		if card_data:
			var card = CardInstance.new(card_data, player_index)
			deck.add_card(card)

	# Shuffle the deck
	deck.shuffle()

## Draw cards from deck to hand
func draw_cards(count: int) -> Array[CardInstance]:
	var drawn: Array[CardInstance] = []

	for i in range(count):
		if deck.is_empty():
			break  # Can't draw from empty deck
		var card = deck.pop_top_card()
		if card:
			hand.add_card(card)
			drawn.append(card)

	return drawn

## Check if player can draw (deck not empty)
func can_draw() -> bool:
	return not deck.is_empty()

## Get current damage count
func get_damage_count() -> int:
	return damage_zone.get_count()

## Check if player has lost (7+ damage)
func has_lost() -> bool:
	return get_damage_count() >= DAMAGE_TO_LOSE

## Take damage (move cards from deck to damage zone)
func take_damage(amount: int) -> Array[CardInstance]:
	var damage_cards: Array[CardInstance] = []

	for i in range(amount):
		if deck.is_empty():
			break
		var card = deck.pop_top_card()
		if card:
			damage_zone.add_card(card)
			damage_cards.append(card)

	return damage_cards

## Discard a card from hand to generate CP
func discard_for_cp(card: CardInstance) -> bool:
	if not hand.has_card(card):
		return false

	# Light/Dark cards cannot be discarded for CP
	if card.is_light_or_dark():
		return false

	hand.remove_card(card)
	break_zone.add_card(card)

	# Generate 2 CP of the card's element
	var element = card.get_element()
	cp_pool.add_cp(element, 2)

	return true

## Dull a backup to generate CP
func dull_backup_for_cp(card: CardInstance) -> bool:
	if not field_backups.has_card(card):
		return false

	if not card.is_backup():
		return false

	if card.is_dull():
		return false

	card.dull()

	# Generate 1 CP of the backup's element
	var element = card.get_element()
	cp_pool.add_cp(element, 1)

	return true

## Play a card from hand to field
func play_card(card: CardInstance) -> bool:
	if not hand.has_card(card):
		return false

	# Check if we can afford it
	if not cp_pool.can_afford_card(card.card_data):
		return false

	# Check field restrictions
	if card.is_backup():
		if field_backups.get_count() >= MAX_BACKUPS:
			return false

	# Check unique name restriction
	if not card.card_data.is_generic:
		if card.is_forward() and field_forwards.has_card_with_name(card.card_data.name):
			return false
		if card.is_backup() and field_backups.has_card_with_name(card.card_data.name):
			return false

	# Check Light/Dark restriction
	if card.is_light_or_dark():
		if field_forwards.has_light_or_dark() or field_backups.has_light_or_dark():
			return false

	# Pay the cost
	if not cp_pool.spend_for_card(card.card_data):
		return false

	# Move to field
	hand.remove_card(card)

	if card.is_forward():
		field_forwards.add_card(card)
		card.state = Enums.CardState.ACTIVE
	elif card.is_backup():
		field_backups.add_card(card)
		card.state = Enums.CardState.DULL  # Backups enter dull

	card.entered_field()

	return true

## Break a card (move from field to break zone)
func break_card(card: CardInstance) -> bool:
	var removed = false

	if field_forwards.has_card(card):
		field_forwards.remove_card(card)
		removed = true
	elif field_backups.has_card(card):
		field_backups.remove_card(card)
		removed = true

	if removed:
		break_zone.add_card(card)
		return true

	return false

## Activate all dull cards (Active Phase)
func activate_all() -> void:
	for card in field_forwards.get_dull_cards():
		card.activate()
	for card in field_backups.get_dull_cards():
		card.activate()

## Discard down to hand size (End Phase)
func discard_to_hand_limit() -> Array[CardInstance]:
	var discarded: Array[CardInstance] = []

	while hand.get_count() > MAX_HAND_SIZE:
		# For now, just discard the last card
		# In actual game, player would choose
		var card = hand.pop_top_card()
		if card:
			break_zone.add_card(card)
			discarded.append(card)

	return discarded

## End of turn cleanup
func end_turn_cleanup() -> void:
	# Clear CP pool
	cp_pool.clear()

	# Reset temporary effects on field cards
	for card in field_forwards.get_cards():
		card.end_turn_cleanup()
	for card in field_backups.get_cards():
		card.end_turn_cleanup()

## Start of turn setup
func start_turn() -> void:
	# Increment turn counter for field cards
	for card in field_forwards.get_cards():
		card.start_turn()
	for card in field_backups.get_cards():
		card.start_turn()

## Get all cards on field
func get_all_field_cards() -> Array[CardInstance]:
	var cards: Array[CardInstance] = []
	cards.append_array(field_forwards.get_cards())
	cards.append_array(field_backups.get_cards())
	return cards

## Get forwards that can attack
func get_attackable_forwards() -> Array[CardInstance]:
	var attackers: Array[CardInstance] = []
	for card in field_forwards.get_cards():
		if card.can_attack():
			attackers.append(card)
	return attackers

## Get forwards that can block
func get_blockable_forwards() -> Array[CardInstance]:
	var blockers: Array[CardInstance] = []
	for card in field_forwards.get_cards():
		if card.can_block():
			blockers.append(card)
	return blockers

func _to_string() -> String:
	return "[Player: %s, Hand: %d, Forwards: %d, Backups: %d, Damage: %d]" % [
		player_name,
		hand.get_count(),
		field_forwards.get_count(),
		field_backups.get_count(),
		damage_zone.get_count()
	]
