class_name CardVisual
extends Node3D

## CardVisual - 3D visual representation of a card

signal clicked(card_visual: CardVisual)
signal hovered(card_visual: CardVisual)
signal unhovered(card_visual: CardVisual)

# Card dimensions (standard card ratio ~2.5:3.5)
const CARD_WIDTH: float = 0.63
const CARD_HEIGHT: float = 0.88
const CARD_THICKNESS: float = 0.02

# Associated card instance
var card_instance: CardInstance = null

# Visual state
var is_highlighted: bool = false
var is_selected: bool = false
var is_hovered: bool = false

# Animation
var target_position: Vector3 = Vector3.ZERO
var target_rotation: Vector3 = Vector3.ZERO
var move_speed: float = 10.0
var is_animating: bool = false

# Components
var mesh_instance: MeshInstance3D
var collision_shape: CollisionShape3D
var static_body: StaticBody3D
var material: StandardMaterial3D

# Colors
var normal_color: Color = Color.WHITE
var highlight_color: Color = Color(1.2, 1.2, 0.8)
var selected_color: Color = Color(0.8, 1.2, 0.8)
var dull_tint: Color = Color(0.7, 0.7, 0.7)

func _ready() -> void:
	_create_card_mesh()
	_setup_collision()

func _create_card_mesh() -> void:
	mesh_instance = MeshInstance3D.new()
	add_child(mesh_instance)

	# Create box mesh for card
	var box = BoxMesh.new()
	box.size = Vector3(CARD_WIDTH, CARD_THICKNESS, CARD_HEIGHT)
	mesh_instance.mesh = box

	# Create material
	material = StandardMaterial3D.new()
	material.albedo_color = Color.WHITE
	mesh_instance.material_override = material

func _setup_collision() -> void:
	static_body = StaticBody3D.new()
	add_child(static_body)

	collision_shape = CollisionShape3D.new()
	var shape = BoxShape3D.new()
	shape.size = Vector3(CARD_WIDTH, CARD_THICKNESS * 2, CARD_HEIGHT)
	collision_shape.shape = shape
	static_body.add_child(collision_shape)

	# Connect input
	static_body.input_event.connect(_on_input_event)
	static_body.mouse_entered.connect(_on_mouse_entered)
	static_body.mouse_exited.connect(_on_mouse_exited)

func _process(delta: float) -> void:
	# Animate position
	if is_animating:
		position = position.lerp(target_position, move_speed * delta)
		rotation = rotation.lerp(target_rotation, move_speed * delta)

		if position.distance_to(target_position) < 0.01 and rotation.distance_to(target_rotation) < 0.01:
			position = target_position
			rotation = target_rotation
			is_animating = false

	# Update dull visual
	_update_visual_state()

## Initialize with a card instance
func setup(card: CardInstance) -> void:
	card_instance = card
	_load_card_texture()
	_update_visual_state()

## Load the card's texture
func _load_card_texture() -> void:
	if not card_instance or not card_instance.card_data:
		return

	var texture = CardDatabase.get_card_texture(card_instance.card_data)
	if texture:
		material.albedo_texture = texture
	else:
		# Use element color as fallback
		var element_color = Enums.element_to_color(card_instance.get_element())
		material.albedo_color = element_color

## Update visual state based on card state
func _update_visual_state() -> void:
	if not material:
		return

	var color = normal_color

	if is_selected:
		color = selected_color
	elif is_highlighted:
		color = highlight_color

	# Apply dull tint
	if card_instance and card_instance.is_dull():
		color = color * dull_tint

	material.albedo_color = color

## Set card as highlighted
func set_highlighted(highlighted: bool) -> void:
	is_highlighted = highlighted
	_update_visual_state()

## Set card as selected
func set_selected(selected: bool) -> void:
	is_selected = selected
	_update_visual_state()

## Move card to position with animation
func move_to(pos: Vector3, rot: Vector3 = Vector3.ZERO) -> void:
	target_position = pos
	target_rotation = rot
	is_animating = true

## Move card instantly
func set_position_instant(pos: Vector3, rot: Vector3 = Vector3.ZERO) -> void:
	position = pos
	rotation = rot
	target_position = pos
	target_rotation = rot
	is_animating = false

## Set dull rotation (90 degrees)
func set_dull_visual(is_dull: bool) -> void:
	if is_dull:
		target_rotation.y = deg_to_rad(90)
	else:
		target_rotation.y = 0
	is_animating = true

## Input handlers
func _on_input_event(_camera: Node, event: InputEvent, _position: Vector3, _normal: Vector3, _shape_idx: int) -> void:
	if event is InputEventMouseButton:
		if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
			clicked.emit(self)

func _on_mouse_entered() -> void:
	is_hovered = true
	hovered.emit(self)
	# Slight raise on hover
	if not is_animating:
		target_position.y = position.y + 0.1
		is_animating = true

func _on_mouse_exited() -> void:
	is_hovered = false
	unhovered.emit(self)
	# Return to normal height
	if not is_animating and card_instance:
		target_position.y = position.y - 0.1
		is_animating = true

## Get display info for UI
func get_card_info() -> Dictionary:
	if not card_instance or not card_instance.card_data:
		return {}

	var data = card_instance.card_data
	return {
		"name": data.name,
		"type": Enums.card_type_to_string(data.type),
		"element": Enums.element_to_string(data.get_primary_element()),
		"cost": data.cost,
		"power": data.power if data.type == Enums.CardType.FORWARD else 0,
		"job": data.job,
		"is_dull": card_instance.is_dull()
	}
