# src/game/game_controller.gd
# Glue layer: connects core logic to UI and AI

class_name GameController
extends Node

signal state_changed()
signal turn_ready(player_idx: int, is_human: bool)
signal game_ended(winner_team: int, reason: String)

var game_state: GameState
var ai_players: Dictionary = {}
var is_processing: bool = false

func start_game(config: RuleConfig, human_idx: int = 0, seed_: int = -1) -> void:
    game_state = GameState.create(config, seed_)
    game_state.player_human[human_idx] = true
    for i in range(4):
        if not game_state.player_human[i]:
            ai_players[i] = L2RuleAI.new()
    var deck := Deck.create(game_state.seed)
    game_state.deal_cards(deck)
    game_state.phase = GameState.Phase.PLAY
    game_state.round.active_player_idx = 0
    state_changed.emit()

func handle_human_play(cards: Array) -> Dictionary:
    if is_processing:
        return {"ok": false, "error_code": 1, "data": null}
    var hand := game_state.get_hand(game_state.round.active_player_idx)
    var play := HandEvaluator.evaluate(cards, game_state.current_rank, game_state.rule_config)
    if play == null or play.type == -1:
        return {"ok": false, "error_code": 1, "data": null}
    var last_idx := game_state.round.last_non_pass_player()
    var result := RuleEngine.can_play(hand, play, game_state.round.table, last_idx, game_state.current_rank, game_state.rule_config)
    if not result.ok:
        return result
    _apply_play(game_state.round.active_player_idx, play)
    _advance_turn()
    return {"ok": true, "error_code": 0, "data": null}

func handle_human_pass() -> Dictionary:
    if is_processing:
        return {"ok": false, "error_code": 1, "data": null}
    var old_last := game_state.round.last_non_pass_player()
    if old_last >= 0 and old_last == game_state.round.active_player_idx:
        return {"ok": false, "error_code": 3, "data": null}
    var pass := HandEvaluator.EvaluatedPlay.new()
    pass.type = -1
    pass.primary_rank = 0
    _apply_play(game_state.round.active_player_idx, pass)
    _advance_turn()
    return {"ok": true, "error_code": 0, "data": null}

func _apply_play(player_idx: int, play: HandEvaluator.EvaluatedPlay) -> void:
    if play.type != -1:
        game_state.remove_cards_from_hand(player_idx, play.cards)
    var action := Actions.Action.new()
    action.player_idx = player_idx
    action.action_type = "PASS" if play.type == -1 else "PLAY"
    action.cards = play.cards.duplicate(false)
    action.seq_id = game_state.round.next_seq()
    action.timestamp = Time.get_unix_time_from_system()
    game_state.action_log.append(action)
    game_state.round.add_play(play, player_idx)
    var hand: Array = game_state.get_hand(player_idx)
    if hand.is_empty() and not game_state.is_player_finished(player_idx):
        game_state.add_finished_player(player_idx)
    if game_state.all_hands_empty():
        _end_game()

func _advance_turn() -> void:
    var hand: Array = game_state.get_hand(game_state.round.active_player_idx)
    if hand.is_empty():
        var partner := game_state.get_partner(game_state.round.active_player_idx)
        if not game_state.is_player_finished(partner):
            game_state.round.active_player_idx = partner
            game_state.round.reset_for_new_round()
        else:
            _next_alive_player()
    elif game_state.round.is_cleared:
        game_state.round.reset_for_new_round()
    else:
        _next_alive_player()
    var current := game_state.round.active_player_idx
    turn_ready.emit(current, game_state.player_human[current])
    if not game_state.player_human[current]:
        _trigger_ai(current)

func _next_alive_player() -> void:
    for _i in range(4):
        game_state.round.active_player_idx = (game_state.round.active_player_idx + 1) % 4
        if not game_state.is_player_finished(game_state.round.active_player_idx):
            return

func _trigger_ai(player_idx: int) -> void:
    var ai := ai_players.get(player_idx)
    if ai == null:
        return
    var hand8: Array = game_state.get_hand(player_idx)
    var decision := ai.decide(hand8, game_state.round.table, game_state.current_rank, game_state.rule_config)
    if decision.type == -1:
        _apply_play(player_idx, decision)
    else:
        _apply_play(player_idx, decision)
    _advance_turn()

func _end_game() -> void:
    game_state.phase = GameState.Phase.GAME_OVER
    var team_counts := [0, 0]
    for fp in game_state.finished_players:
        var t := game_state.get_team(fp)
        if t != null:
            team_counts[t.team_id] += 1
    if team_counts[0] >= 2:
        game_state.current_winner_team = 0
    elif team_counts[1] >= 2:
        game_state.current_winner_team = 1
    else:
        game_state.current_winner_team = 0 if team_counts[0] > team_counts[1] else 1
    game_state.game_end_reason = "NORMAL"
    game_ended.emit(game_state.current_winner_team, "NORMAL")
