#pragma once
#include "feature_manager.h"
#include "esp_config.h"
#include "../memory/memory_reader.h"
#include "../memory/offsets.h"
#include "../OS-ImGui/imgui/imgui.h"
#include "entity.h"
#include "math.h"

class ESPFeature : public IFeature {
public:
    ESPConfig config;

    ESPFeature() = default;
    
    
    const char* GetName() const override { return "ESP"; }
    bool IsEnabled() const override { return config.enabled; }
    void SetEnabled(bool enabled) override { config.enabled = enabled; }
    
    
    void Update(uintptr_t localPlayerPtr, uintptr_t gameBase) override {
        
        
    }
    
    
    void DrawHealthAndShieldBar(ImDrawList* drawList, const ImVec2& topLeft, const ImVec2& bottomRight, 
                                 int health, int maxHealth, int shield, int maxShield, int armorType) {
        float barWidth = 4.0f; // 稍微加宽一点
        float totalHeight = bottomRight.y - topLeft.y;
        float barX = topLeft.x - barWidth - 4.0f; // 离方框稍远一点
        
        // --- 绘制血条 ---
        if (maxHealth > 0) {
            float healthPct = std::clamp((float)health / (float)maxHealth, 0.0f, 1.0f);
            float healthHeight = totalHeight * healthPct;
            
            // 背景（带阴影/边框效果）
            drawList->AddRectFilled(
                ImVec2(barX - 1, topLeft.y - 1),
                ImVec2(barX + barWidth + 1, bottomRight.y + 1),
                IM_COL32(0, 0, 0, 200)
            );
            
            drawList->AddRectFilled(
                ImVec2(barX, topLeft.y),
                ImVec2(barX + barWidth, bottomRight.y),
                IM_COL32(20, 20, 20, 180)
            );
            
            // 血条颜色逻辑
            ImU32 healthColor;
            if (healthPct > 0.7f) healthColor = IM_COL32(0, 255, 0, 255); // 绿
            else if (healthPct > 0.3f) healthColor = IM_COL32(255, 255, 0, 255); // 黄
            else healthColor = IM_COL32(255, 0, 0, 255); // 红
            
            drawList->AddRectFilled(
                ImVec2(barX, bottomRight.y - healthHeight),
                ImVec2(barX + barWidth, bottomRight.y),
                healthColor
            );

            // 绘制血条刻度（每 25 血一个分段）
            if (maxHealth > 25) {
                for (int i = 1; i < (maxHealth / 25); i++) {
                    float segY = bottomRight.y - (totalHeight * (i * 25.0f / maxHealth));
                    drawList->AddLine(ImVec2(barX, segY), ImVec2(barX + barWidth, segY), IM_COL32(0, 0, 0, 150));
                }
            }
        }
        
        // --- 绘制护甲条 ---
        if (maxShield > 0) {
            // 如果有血条，护甲条在血条左边；如果没有，在方框左边
            float shieldBarX = (maxHealth > 0) ? (barX - barWidth - 3.0f) : barX;
            float shieldPct = std::clamp((float)shield / (float)maxShield, 0.0f, 1.0f);
            float shieldHeight = totalHeight * shieldPct;
            
            // 背景
            drawList->AddRectFilled(
                ImVec2(shieldBarX - 1, topLeft.y - 1),
                ImVec2(shieldBarX + barWidth + 1, bottomRight.y + 1),
                IM_COL32(0, 0, 0, 200)
            );
            
            drawList->AddRectFilled(
                ImVec2(shieldBarX, topLeft.y),
                ImVec2(shieldBarX + barWidth, bottomRight.y),
                IM_COL32(20, 20, 20, 180)
            );
            
            // 护甲颜色
            ImU32 shieldColor = IM_COL32(255, 255, 255, 255); // 白
            if (armorType == 2) shieldColor = IM_COL32(0, 180, 255, 255); // 蓝
            else if (armorType == 3) shieldColor = IM_COL32(200, 0, 255, 255); // 紫
            else if (armorType == 4) shieldColor = IM_COL32(255, 200, 0, 255); // 金
            else if (armorType == 5) shieldColor = IM_COL32(255, 50, 50, 255); // 红
            
            drawList->AddRectFilled(
                ImVec2(shieldBarX, bottomRight.y - shieldHeight),
                ImVec2(shieldBarX + barWidth, bottomRight.y),
                shieldColor
            );

            // 绘制护甲刻度
            if (maxShield > 25) {
                for (int i = 1; i < (maxShield / 25); i++) {
                    float segY = bottomRight.y - (totalHeight * (i * 25.0f / maxShield));
                    drawList->AddLine(ImVec2(shieldBarX, segY), ImVec2(shieldBarX + barWidth, segY), IM_COL32(0, 0, 0, 150));
                }
            }
        }
    }

    void DrawSkeleton(ImDrawList* drawList, Entity& entity, const Matrix& viewMatrix, ImU32 color, float thickness) {
        if (!entity.hasBones || entity.cachedBones.empty())
            return;

        extern Vector2 g_ScreenSize;
        auto GetScreenPos = [&](int indexInList) -> Vector2 {
            return WorldToScreen(entity.cachedBones[indexInList], viewMatrix, g_ScreenSize.x, g_ScreenSize.y);
        };

        auto DrawBoneLine = [&](int idx1, int idx2) {
            Vector2 p1 = GetScreenPos(idx1);
            Vector2 p2 = GetScreenPos(idx2);
            if (p1.IsValid(g_ScreenSize.x, g_ScreenSize.y) && p2.IsValid(g_ScreenSize.x, g_ScreenSize.y)) {
                drawList->AddLine(ImVec2(p1.x, p1.y), ImVec2(p2.x, p2.y), IM_COL32(0, 0, 0, 200), thickness + 1.0f);
                drawList->AddLine(ImVec2(p1.x, p1.y), ImVec2(p2.x, p2.y), color, thickness);
            }
        };

        // 身体主轴
        DrawBoneLine(0, 1); // Head to Neck
        DrawBoneLine(1, 2); // Neck to Chest
        DrawBoneLine(2, 3); // Chest to Pelvis
        
        // 左臂
        DrawBoneLine(2, 4); // Chest to L_Shoulder
        DrawBoneLine(4, 5); // L_Shoulder to L_Elbow
        DrawBoneLine(5, 6); // L_Elbow to L_Hand
        
        // 右臂
        DrawBoneLine(2, 7); // Chest to R_Shoulder
        DrawBoneLine(7, 8); // R_Shoulder to R_Elbow
        DrawBoneLine(8, 9); // R_Elbow to R_Hand
        
        // 左腿
        DrawBoneLine(3, 10); // Pelvis to L_Hip
        DrawBoneLine(10, 11); // L_Hip to L_Knee
        DrawBoneLine(11, 12); // L_Knee to L_Foot
        
        // 右腿
        DrawBoneLine(3, 13); // Pelvis to R_Hip
        DrawBoneLine(13, 14); // R_Hip to R_Knee
        DrawBoneLine(14, 15); // R_Knee to R_Foot
    }
    
    void DrawPlayerInfo(ImDrawList* drawList, const ImVec2& pos, const Entity& entity, float distance, bool showNames = true) {
        ImVec2 textPos = pos;
        float lineHeight = 14.0f;
        
        
        if (config.showDistances) {
            char distStr[32];
            sprintf_s(distStr, "%.0fm", distance);
            drawList->AddText(textPos, IM_COL32(200, 200, 200, 255), distStr);
            textPos.y += lineHeight;
        }
        
        
        if (entity.isKnocked && distance <= 200.0f) {
            drawList->AddText(textPos, IM_COL32(255, 0, 0, 255), "KNOCKED");
        }
    }
};
