//
// GameStateDumper.cpp
// Utility for dumping game state to file for debugging
//

#include "GameStateDumper.hpp"

#include <fstream>
#include <iostream>

namespace shardok {

void DumpGameStateToFile(const GameStateW& gameState, const std::string& gameId) {
    const std::string filePath = "/tmp/shardok_setup_complete_" + gameId + ".txt";
    std::ofstream out(filePath);
    if (!out.is_open()) {
        std::cerr << "Failed to open " << filePath << " for writing\n";
        return;
    }

    out << "==================== GAME STATE DUMP ====================\n\n";
    out << "Game ID: " << gameId << "\n\n";

    // Game status
    out << "Current Player: " << (int)gameState->current_player() << "\n";
    out << "Current Round: " << (int)gameState->current_round() << "\n";
    out << "Game State: ";
    switch (gameState->status()->state()) {
        case net::eagle0::shardok::storage::fb::GameStatus_::State_SET_UP: out << "SET_UP\n"; break;
        case net::eagle0::shardok::storage::fb::GameStatus_::State_GAME_RUNNING:
            out << "GAME_RUNNING\n";
            break;
        case net::eagle0::shardok::storage::fb::GameStatus_::State_VICTORY:
            out << "VICTORY\n";
            break;
        case net::eagle0::shardok::storage::fb::GameStatus_::State_DRAW: out << "DRAW\n"; break;
        default: out << "UNKNOWN\n";
    }
    out << "\n";

    // Units
    out << "==================== UNITS ====================\n\n";
    const auto* units = gameState->units();
    if (units) {
        for (const auto* unit : *units) {
            if (!unit) continue;

            out << "Unit ID: " << unit->unit_id() << "\n";
            out << "  Player ID: " << (int)unit->player_id() << "\n";
            out << "  Location: (" << (int)unit->location().row() << ", "
                << (int)unit->location().column() << ")\n";
            out << "  Starting Position Index: " << (int)unit->starting_position_index() << "\n";
            out << "  Status: ";
            switch (unit->status()) {
                case net::eagle0::shardok::storage::fb::UnitStatus_NORMAL_UNIT:
                    out << "NORMAL_UNIT\n";
                    break;
                case net::eagle0::shardok::storage::fb::UnitStatus_RESERVE_UNIT:
                    out << "RESERVE_UNIT\n";
                    break;
                case net::eagle0::shardok::storage::fb::UnitStatus_NEVER_ENTERED_UNIT:
                    out << "NEVER_ENTERED_UNIT\n";
                    break;
                case net::eagle0::shardok::storage::fb::UnitStatus_FLED_UNIT:
                    out << "FLED_UNIT\n";
                    break;
                case net::eagle0::shardok::storage::fb::UnitStatus_CAPTURED_UNIT:
                    out << "CAPTURED_UNIT\n";
                    break;
                case net::eagle0::shardok::storage::fb::UnitStatus_DESTROYED_SUMMONED_UNIT:
                    out << "DESTROYED_SUMMONED_UNIT\n";
                    break;
                case net::eagle0::shardok::storage::fb::UnitStatus_RETREATED_UNIT:
                    out << "RETREATED_UNIT\n";
                    break;
                default: out << "OTHER (" << (int)unit->status() << ")\n";
            }
            out << "  Remaining Action Points: " << (int)unit->remaining_action_points() << "\n";
            out << "  Can Flee: " << (unit->can_flee() ? "true" : "false") << "\n";
            out << "  Fortified: " << (unit->fortified() ? "true" : "false") << "\n";
            out << "  Hidden: " << (unit->hidden() ? "true" : "false") << "\n";

            // Battalion info
            const auto& battalion = unit->battalion();
            out << "  Battalion Type: " << (int)battalion.type() << "\n";
            out << "  Battalion Size: " << battalion.size() << "\n";
            out << "  Battalion Armament: " << battalion.armament() << "\n";
            out << "  Battalion Training: " << battalion.training() << "\n";
            out << "  Battalion Morale: " << battalion.morale() << "\n";

            // Hero info
            if (unit->has_attached_hero()) {
                const auto& hero = unit->attached_hero();
                out << "  Has Hero: true\n";
                out << "    Profession: " << (int)hero.profession_info().profession() << "\n";
                out << "    Strength: " << (int)hero.strength() << "\n";
                out << "    Agility: " << (int)hero.agility() << "\n";
                out << "    Wisdom: " << (int)hero.wisdom() << "\n";
                out << "    Charisma: " << (int)hero.charisma() << "\n";
                out << "    Constitution: " << (int)hero.constitution() << "\n";
                out << "    Bravery: " << (int)hero.bravery() << "\n";
                out << "    Integrity: " << (int)hero.integrity() << "\n";
                out << "    Ambition: " << (int)hero.ambition() << "\n";
                out << "    Vigor: " << (int)hero.vigor() << "/" << (int)hero.starting_vigor()
                    << "\n";
            } else {
                out << "  Has Hero: false\n";
            }

            // Opponent knowledge
            out << "  Opponent Knowledge:\n";
            const auto* opponentKnowledge = unit->opponent_knowledge();
            if (opponentKnowledge && opponentKnowledge->size() >= 2) {
                out << "    Player 0: " << (int)opponentKnowledge->Get(0) << "\n";
                out << "    Player 1: " << (int)opponentKnowledge->Get(1) << "\n";
            }

            out << "\n";
        }
    }

    out << "==================== END DUMP ====================\n";
    out.close();

    std::cout << "Game state after setup dumped to " << filePath << "\n";
}

}  // namespace shardok
