#include "aimbot.h"
#include "math.h"
#include "entity.h"
#include "../OS-ImGui/imgui/imgui.h"
#include <cmath>
#include <algorithm>
#include <mutex>
#include <random>
#include "../security/license.h"

extern std::vector<Entity> g_Entities;
extern std::mutex g_EntityMutex;
extern Vector3 g_LocalPos;
extern int g_LocalTeam;
extern Matrix g_ViewMatrix;
extern Vector2 g_ScreenSize;
extern float g_ProjectileSpeed;
extern float g_ProjectileScale;
extern Vector3 g_PunchAngles; 

extern bool g_IsInFiringRange;

Aimbot::Aimbot(DriverInterfaceV3* drv)
    : driver(drv) {
}

bool Aimbot::IsHoldKeyActive() const {
    if (config.aimKey == 0) return true; // 如果没设按键，默认开启
    
    // 强制检查：支持鼠标左键(1)、右键(2)和其他按键
    short state = GetAsyncKeyState(config.aimKey);
    return (state & 0x8000) != 0 || (state & 0x0001) != 0;
}

Vector2 Aimbot::WorldToScreenSafe(const Vector3& worldPos) const {
    return WorldToScreen(worldPos, g_ViewMatrix, g_ScreenSize.x, g_ScreenSize.y);
}

Vector3 Aimbot::ApplyPrediction(const Vector3& targetPos, const Entity& target, const Vector3& localPos) {
    if (!config.usePrediction) {
        return targetPos;
    }

    float dx = targetPos.x - localPos.x;
    float dy = targetPos.y - localPos.y;
    float dz = targetPos.z - localPos.z;
    float distance = std::sqrt(dx * dx + dy * dy + dz * dz);

    if (distance < 600.0f || g_ProjectileSpeed <= 0.0f) {
        return targetPos;
    }

    float timeToHit = distance / g_ProjectileSpeed;
    if (timeToHit <= 0.0f || timeToHit > 0.8f) {
        return targetPos;
    }

    Vector3 predicted = {
        targetPos.x + target.velocity.x * timeToHit,
        targetPos.y + target.velocity.y * timeToHit,
        targetPos.z + target.velocity.z * timeToHit
    };

    float drop = 0.5f * g_ProjectileScale * timeToHit * timeToHit;
    predicted.z -= drop;
    return predicted;
}

bool Aimbot::FindBestTarget(const std::vector<Entity>& entities, uintptr_t localPlayer, Entity& outTarget, Vector3& outTargetPos) {
    if (!localPlayer) return false;

    float bestFov = config.fovDegrees;
    bool found = false;

    for (const auto& ent : entities) {
        if (!ent.valid) continue;
        if (ent.address == 0) continue;
        
        // 如果不是训练场，进行常规过滤
        if (!g_IsInFiringRange) {
            if (ent.health <= 0) continue;
            if (ent.isKnocked) continue;
            if (ent.team == g_LocalTeam && !ent.isDummy) continue;
        } else {
            // 训练场：只过滤完全无效的（坐标为0）
            if (ent.position.x == 0 && ent.position.y == 0) continue;
            // 过滤自己
            if (ent.address == localPlayer) continue;
        }
        
        // 可见性检查
        if (config.onlyVisible && !ent.isVisible) {
            continue;
        }

        // 获取目标骨骼位置
        Vector3 targetPos;
        int targetBone = 0; // 默认头部
        switch (config.boneMode) {
            case 0: targetBone = 0; break; // 头
            case 1: targetBone = 1; break; // 颈
            case 2: targetBone = 2; break; // 胸
            case 3: targetBone = 3; break; // 腹
            default: targetBone = 0; break;
        }

        targetPos = const_cast<Entity&>(ent).GetBonePosition(targetBone);
        
        // 如果骨骼读取失败（例如距离太远或地址无效），则回退到基础坐标+高度偏移
        if (targetPos.x == 0 && targetPos.y == 0) {
            targetPos = ent.position;
            targetPos.z += 60.0f;
        }

        // 应用预测
        targetPos = ApplyPrediction(targetPos, ent, g_LocalPos);

        
        if (config.compensateRecoil) {
            float strength = std::clamp(config.recoilStrength, 0.0f, 1.0f);
            
            
            targetPos.z += g_PunchAngles.x * 0.3f * strength;
        }

        Vector2 screenPos = WorldToScreenSafe(targetPos);
        if (!screenPos.IsValid(g_ScreenSize.x, g_ScreenSize.y)) continue;

        
        float screenCenterX = g_ScreenSize.x * 0.5f;
        float screenCenterY = g_ScreenSize.y * 0.5f;
        float dx = screenPos.x - screenCenterX;
        float dy = screenPos.y - screenCenterY;

        float distPixels = std::sqrt(dx * dx + dy * dy);
        if (distPixels <= 0.0f) continue;

        
        float fov = std::atan2(distPixels, g_ScreenSize.y) * (180.0f / 3.14159265f) * 2.0f;
        if (fov < bestFov) {
            bestFov = fov;
            outTarget = const_cast<Entity&>(ent);
            outTargetPos = targetPos;
            found = true;
        }
    }

    return found;
}

void Aimbot::MoveMouseTowards(const Vector2& targetScreenPos) {
    if (!driver) return;

    static DWORD lastMoveTime = 0;
    DWORD now = GetTickCount();

    
    if (lastMoveTime != 0) {
        DWORD deltaMs = now - lastMoveTime;
        if (deltaMs < 5) {
            return;
        }
    }

    float screenCenterX = g_ScreenSize.x * 0.5f;
    float screenCenterY = g_ScreenSize.y * 0.5f;

    float dx = targetScreenPos.x - screenCenterX;
    float dy = targetScreenPos.y - screenCenterY;

    float distPixels = std::sqrt(dx * dx + dy * dy);
    if (distPixels <= 0.5f) {
        return;
    }

    
    
    
    float clampedSmooth = std::clamp(config.smooth, 0.0f, 1.0f);

    float adaptiveFactor = 1.0f;
    if (distPixels > 250.0f) {
        adaptiveFactor = 1.1f;
    } else if (distPixels < 80.0f && config.aggressiveWhenClose) {
        adaptiveFactor = 0.5f; 
    }

    float aggression = std::clamp(config.aggression, 0.5f, 2.0f);

    float smoothFactor = clampedSmooth * adaptiveFactor / aggression;
    smoothFactor = std::clamp(smoothFactor, 0.0f, 1.0f);

    if (smoothFactor > 0.0f) {
        // 进一步降低平滑度对初始移动的影响
        dx *= (1.0f - smoothFactor * 0.8f);
        dy *= (1.0f - smoothFactor * 0.8f);
    }

    // 强制最小移动量：只要 dx/dy 存在，就至少移动 1 像素
    if (std::abs(dx) > 0.01f && std::abs(dx) < 1.0f) dx = (dx > 0 ? 1.0f : -1.0f);
    if (std::abs(dy) > 0.01f && std::abs(dy) < 1.0f) dy = (dy > 0 ? 1.0f : -1.0f);

    // 限制单次移动的最大步长
    float maxStep = 30.0f * aggression; 
    float stepLen = std::sqrt(dx * dx + dy * dy);
    if (stepLen > maxStep && stepLen > 0.0f) {
        float scale = maxStep / stepLen;
        dx *= scale;
        dy *= scale;
    }

    if (std::abs(dx) < 0.1f && std::abs(dy) < 0.1f) return;

    driver->InjectMouseMove(dx, dy);
    lastMoveTime = now;
}

extern DWORD g_ApexPid;
extern Vector3 g_LocalPos;

Vector3 Aimbot::CalculateAngles(const Vector3& source, const Vector3& destination) {
    Vector3 angles;
    Vector3 delta = source - destination;
    float hyp = std::sqrt(delta.x * delta.x + delta.y * delta.y);

    angles.x = std::atan2(delta.z, hyp) * (180.0f / 3.14159265f);
    angles.y = std::atan2(delta.y, delta.x) * (180.0f / 3.14159265f);
    angles.z = 0.0f;

    // Normalize angles
    if (angles.y > 180.0f) angles.y -= 360.0f;
    if (angles.y < -180.0f) angles.y += 360.0f;
    if (angles.x > 89.0f) angles.x = 89.0f;
    if (angles.x < -89.0f) angles.x = -89.0f;

    return angles;
}

void Aimbot::ExecuteSilentAim(uintptr_t localPlayerPtr, const Vector3& targetPos) {
    if (!localPlayerPtr || !driver) return;

    // 1. 获取本地玩家相机坐标 (Eye Position)
    Vector3 viewOffset;
    if (!driver->ReadMemory(g_ApexPid, localPlayerPtr + 0x0034, &viewOffset, sizeof(Vector3))) { // 0x0034 = m_vecViewOffset
        return;
    }
    Vector3 eyePos = g_LocalPos + viewOffset;

    // 2. 计算目标角度
    Vector3 targetAngle = CalculateAngles(eyePos, targetPos);

    // 3. Write-and-Restore 核心逻辑
    Vector3 originalAngle;
    uintptr_t angleAddr = localPlayerPtr + OFF_VIEW_ANGLES;

    // 读取当前视角
    if (driver->ReadMemory(g_ApexPid, angleAddr, &originalAngle, sizeof(Vector3))) {
        // 写入目标视角
        driver->WriteMemory(g_ApexPid, angleAddr, &targetAngle, sizeof(Vector3));
        
        // 恢复原始视角
        driver->WriteMemory(g_ApexPid, angleAddr, &originalAngle, sizeof(Vector3));
    }
}

void Aimbot::Update(uintptr_t localPlayerPtr, uintptr_t gameBase) {
 
    if (!RuntimeSync::VerifyHeader()) {
        ExitProcess(0);
    }

    try {
        if (!config.enabled) return;
        if (!driver) return;
        if (!IsHoldKeyActive()) return;

        std::vector<Entity> entities;
        {
            std::lock_guard<std::mutex> lock(g_EntityMutex);
            entities = g_Entities;
        }

        if (entities.empty()) return;

        Entity bestTarget;
        Vector3 bestPos;

        
        if (config.lockOnTarget && currentTargetAddress != 0) {
            bool foundExisting = false;
            for (const auto& ent : entities) {
                if (!ent.valid || ent.address == 0) continue;
                if (ent.address != currentTargetAddress) continue;
                if (ent.health <= 0 || ent.isKnocked) continue;

                bestTarget = const_cast<Entity&>(ent);
                
                // 同样需要获取骨骼位置
                int targetBone = 0;
                switch (config.boneMode) {
                    case 0: targetBone = 0; break;
                    case 1: targetBone = 1; break;
                    case 2: targetBone = 2; break;
                    case 3: targetBone = 3; break;
                    default: targetBone = 4; break;
                }
                bestPos = bestTarget.GetBonePosition(targetBone);
                if (bestPos.x == 0 && bestPos.y == 0) {
                    bestPos = ent.position;
                    bestPos.z += 60.0f;
                }
                
                bestPos = ApplyPrediction(bestPos, ent, g_LocalPos);
                foundExisting = true;
                break;
            }

            if (!foundExisting) {
                currentTargetAddress = 0;
            }
        }

        if (currentTargetAddress == 0 || !config.lockOnTarget) {
            if (!FindBestTarget(entities, localPlayerPtr, bestTarget, bestPos)) return;
            currentTargetAddress = config.lockOnTarget ? bestTarget.address : 0;
        }

        Vector2 screenPos = WorldToScreenSafe(bestPos);
        if (!screenPos.IsValid(g_ScreenSize.x, g_ScreenSize.y)) return;

        // 检查静默自瞄逻辑
        if (config.silentAim) {
            bool shouldSilent = true;
            if (config.onlySilentOnFire) {
                // 检查是否正在攻击
                uint8_t inAttack = 0;
                driver->ReadMemory(g_ApexPid, gameBase + OFF_INATTACK, &inAttack, sizeof(uint8_t));
                if (!(inAttack & 1)) {
                    shouldSilent = false;
                }
            }

            if (shouldSilent) {
                ExecuteSilentAim(localPlayerPtr, bestPos);
                return; // 如果执行了静默自瞄，通常不需要再移动鼠标，或者可以根据需要保留
            }
        }

        MoveMouseTowards(screenPos);
    } catch (...) {
        
    }
}

void Aimbot::RenderMenu() {
    ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(8, 8));
    ImGui::Checkbox(u8"启用自动瞄准", &config.enabled);
    ImGui::PopStyleVar();

    ImGui::Spacing();
    ImGui::Separator();
    ImGui::Spacing();

    ImGui::Text(u8"瞄准范围 (FOV)");
    ImGui::SliderFloat("##AimbotFOV", &config.fovDegrees, 1.0f, 20.0f, "%.1f");

    ImGui::Spacing();

    ImGui::Text(u8"平滑度");
    ImGui::SliderFloat("##AimbotSmooth", &config.smooth, 0.0f, 1.0f, "%.2f");

    ImGui::Spacing();

    ImGui::Text(u8"力度 (Aggression)");
    ImGui::SliderFloat("##AimbotAgg", &config.aggression, 0.5f, 2.0f, "%.2f");

    ImGui::Spacing();
    ImGui::Separator();
    ImGui::Spacing();

    ImGui::Checkbox(u8"静默自瞄 (Write-and-Restore)", &config.silentAim);
    if (config.silentAim) {
        ImGui::SameLine();
        ImGui::Checkbox(u8"仅开火时静默", &config.onlySilentOnFire);
    }

    ImGui::Checkbox(u8"仅瞄准可见目标", &config.onlyVisible);

    ImGui::Spacing();
    ImGui::Separator();
    ImGui::Spacing();

    
    ImGui::Text(u8"目标部位");
    const char* boneOptions[] = { u8"头部", u8"颈部", u8"胸部", u8"腹部" };
    ImGui::Combo("##AimbotBone", &config.boneMode, boneOptions, IM_ARRAYSIZE(boneOptions));

    ImGui::Spacing();
    ImGui::Separator();
    ImGui::Spacing();

    
    static bool selectingKey = false;

    ImGui::Text(u8"自瞄按键 (按住)");
    ImGui::SameLine();

    char keyName[64];
    if (selectingKey) {
        strcpy_s(keyName, u8"请按任意键...");
    } else {
        if (config.aimKey == 0) {
            strcpy_s(keyName, u8"无");
        } else {
            switch (config.aimKey) {
                case VK_LBUTTON: strcpy_s(keyName, u8"鼠标左键"); break;
                case VK_RBUTTON: strcpy_s(keyName, u8"鼠标右键"); break;
                case VK_MBUTTON: strcpy_s(keyName, u8"鼠标中键"); break;
                case VK_XBUTTON1: strcpy_s(keyName, u8"侧键 4"); break;
                case VK_XBUTTON2: strcpy_s(keyName, u8"侧键 5"); break;
                case VK_SHIFT: strcpy_s(keyName, u8"Shift"); break;
                case VK_CONTROL: strcpy_s(keyName, u8"Ctrl"); break;
                case VK_MENU: strcpy_s(keyName, u8"Alt"); break;
                default: sprintf_s(keyName, u8"按键 %d", config.aimKey); break;
            }
        }
    }

    if (ImGui::Button(keyName, ImVec2(140, 24))) {
        selectingKey = true;
    }

    if (selectingKey) {
        for (int i = 3; i < 255; i++) {
            if (GetAsyncKeyState(i) & 0x8000) {
                if (i == VK_LBUTTON) continue;
                config.aimKey = i;
                selectingKey = false;
                break;
            }
        }
        if (GetAsyncKeyState(VK_ESCAPE) & 0x8000) {
            selectingKey = false;
        }
    }

    ImGui::Spacing();

    ImGui::Checkbox("Use Prediction", &config.usePrediction);
    ImGui::Checkbox("Draw FOV Circle", &config.drawFovCircle);

    ImGui::Spacing();
    ImGui::Separator();
    ImGui::Spacing();

    ImGui::Text("Recoil");
    ImGui::Checkbox("Enable Recoil Compensation", &config.compensateRecoil);
    ImGui::SliderFloat("##AimbotRecoilStr", &config.recoilStrength, 0.0f, 1.0f, "Strength %.2f");

    ImGui::Spacing();
    ImGui::Separator();
    ImGui::Spacing();

    ImGui::Checkbox("Aggressive When Close", &config.aggressiveWhenClose);
    ImGui::Checkbox("Lock On Target", &config.lockOnTarget);

    ImGui::Spacing();
    ImGui::Separator();
    ImGui::Spacing();

    // 调试信息
    if (config.enabled) {
        if (currentTargetAddress != 0) {
            ImGui::TextColored(ImVec4(0, 1, 0, 1), u8"当前目标: %llX", currentTargetAddress);
        } else {
            ImGui::TextColored(ImVec4(1, 1, 0, 1), u8"正在寻找目标...");
        }
        
        if (g_IsInFiringRange) {
            ImGui::TextColored(ImVec4(0, 0.8f, 1, 1), u8"模式: 训练场 (已解除过滤)");
        } else {
            ImGui::TextColored(ImVec4(1, 0.5f, 0, 1), u8"模式: 标准匹配");
        }
    }
}
