#include "brain/bot_brain.hpp"
#include "navigation/movement_controller.hpp"

#include <iostream>
#include <cmath>
#include <climits>

void BotBrain::AddHandler(IActionHandler* handler) {
    if (handler != nullptr) {
        m_handlers.push_back(handler);
    }
}

void BotBrain::ClearHandlers() {
    m_handlers.clear();
    m_lastChosen = ActionProposal{};
    m_lastLoggedKind = BotActionKind::None;
    m_lastLoggedEntityId = 0;
    m_lastLogMs = 0;
}

bool BotBrain::Process(const TelemetryPacket& packet, KMBoxNet& kmbox, uint64_t nowMs) {
    ActionProposal best{};
    best.priority = 0;
    best.kind = BotActionKind::None;
    IActionHandler* bestHandler = nullptr;

    for (auto* handler : m_handlers) {
        if (!handler) continue;

        ActionProposal p = handler->Propose(packet, nowMs);
        if (p.priority == 0 || p.kind == BotActionKind::None) {
            continue;
        }

        bool beats = false;
        if (p.priority > best.priority) {
            beats = true;
        } else if (p.priority == best.priority) {
            // Tie-break 1: cự ly mục tiêu gần hơn thắng
            if (p.distance < best.distance - 0.001f) {
                beats = true;
            } else if (std::abs(p.distance - best.distance) <= 0.001f) {
                // Tie-break 2: entityId nhỏ hơn thắng (entityId == 0 coi như UINT32_MAX để ưu tiên thực thể thật)
                const uint32_t pId = (p.entityId == 0) ? UINT32_MAX : p.entityId;
                const uint32_t bestId = (best.entityId == 0) ? UINT32_MAX : best.entityId;
                if (pId < bestId) {
                    beats = true;
                }
            }
        }

        if (beats) {
            best = p;
            bestHandler = handler;
        }
    }

    if (best.priority == 0 || bestHandler == nullptr) {
        if (m_moveCtrl) {
            m_moveCtrl->Stop(kmbox);
        }
        m_lastChosen = ActionProposal{};
        m_lastChosen.kind = BotActionKind::Idle;
        m_lastChosen.priority = bot_priority::IDLE;
        m_lastChosen.priorityName = "IDLE";
        return false;
    }

    // Nếu hành động thắng cuộc là hành động tĩnh (nhặt đồ, mở hòm, giao tiếp NPC, rương),
    // lập tức giải phóng phím di chuyển để tránh nhân vật vừa bước đi vừa click sai lệch hitbox
    if (m_moveCtrl && best.kind != BotActionKind::Explore && best.kind != BotActionKind::Combat) {
        m_moveCtrl->Stop(kmbox);
    }

    m_lastChosen = best;

    // Thực thi duy nhất hành động thắng cuộc
    const bool executed = bestHandler->Execute(best, packet, kmbox, nowMs);

    // Bất biến INV-BRAIN-05: Ghi log chuẩn định dạng
    // Running {Kind} with priority: {Name} ({n}) entity={id}
    if (m_logEnabled && executed) {
        const bool kindChanged = (best.kind != m_lastLoggedKind);
        const bool entityChanged = (best.entityId != m_lastLoggedEntityId);
        const bool timeElapsed = (nowMs - m_lastLogMs >= 1000);

        if (kindChanged || entityChanged || timeElapsed) {
            std::cout << "Running " << BotActionKindToString(best.kind)
                      << " with priority: " << (best.priorityName ? best.priorityName : "UNKNOWN")
                      << " (" << best.priority << ") entity=" << best.entityId << std::endl;
            m_lastLoggedKind = best.kind;
            m_lastLoggedEntityId = best.entityId;
            m_lastLogMs = nowMs;
        }
    }

    return executed;
}
