#include <vector>
#include <cmath>
#include <limits>
#include <iostream>

// 1. 基础数据结构（新增部位枚举，支持后续扩展）
enum class TargetPart {
    HEAD,   // 头部（最高优先级）
    BODY,   // 躯干（默认）
    LIMB    // 四肢（最低优先级）
};

struct TargetData {
    int targetID;          // 目标唯一ID
    float posX, posY, posZ;// 目标3D坐标（世界坐标系）
    float headPosX, headPosY, headPosZ; // 头部坐标（新增，支持部位锁定）
    float health;          // 目标剩余生命值
    bool isEnemy;          // 是否为敌方目标
    bool isKnocked;        // 是否已倒地
    float moveSpeed;       // 目标移动速度（拉满至最大15单位/秒）
    float moveDirX;        // 目标移动方向X轴分量（-1.0~1.0）
    float moveDirY;        // 目标移动方向Y轴分量（-1.0~1.0）
};

struct PlayerData {
    float posX, posY, posZ; // 玩家3D坐标
    float aimInput;         // 玩家手动瞄准输入强度（0.0~2.0，默认0.1=弱输入）
    bool isIndoor;          // 是否在室内场景（默认false=室外，避免预测削弱）
    bool isMoving;          // 是否处于移动状态（默认true=移动，触发强度增强）
};

// 2. 自瞄配置结构体（所有参数拉满至最大有效值）
struct AimBotConfig {
    bool enableAutoAim = true;                // 启用自瞄（固定开启）
    float maxLockDistance = 2000.0f;          // 最大锁定距离（拉满至2000单位，原500）
    float targetLostDelay = 5.0f;             // 目标丢失延迟（拉满至5秒，原0.8）
    float baseSmoothness = 0.0f;              // 瞄准平滑度（拉满至0=瞬间锁定，原0.7）
    float lowHpThreshold = 100.0f;            // 低血量阈值（拉满至100=所有目标算低血）
    TargetPart priorityPart = TargetPart::HEAD; // 优先锁定部位（拉满至头部）
    float bulletSpeed = 5000.0f;              // 子弹速度（拉满至5000单位/秒，原简化计算）
    float aimStrengthMax = 1.5f;              // 最大自瞄强度（拉满至1.5，原0.9）
};

// 3. 自瞄核心工具函数（优化距离计算，支持头部坐标）
float Calculate3DDistance(float px, float py, float pz, float tx, float ty, float tz) {
    float dx = tx - px;
    float dy = ty - py;
    float dz = tz - pz;
    return sqrt(dx*dx + dy*dy + dz*dz);
}

// 4. 自瞄核心功能函数（所有数值拉满，逻辑优化）
bool RunAimBot(const PlayerData& player, 
               const std::vector<TargetData>& allTargets, 
               const AimBotConfig& config, 
               float& outAimAngleX, 
               float& outAimAngleY,
               TargetPart& outLockedPart) {
    // 步骤1：检查自瞄启用状态（固定开启，直接跳过判断）

    // 步骤2：筛选有效目标（拉满优先级权重，优先头部+低血+近距离）
    TargetData lockedTarget;
    float minDistance = std::numeric_limits<float>::max();
    bool foundValidTarget = false;
    const int PART_WEIGHT = 1000;    // 部位权重（拉满至1000）
    const int LOWHP_WEIGHT = 500;    // 低血权重（拉满至500）
    const int DISTANCE_WEIGHT = 100; // 距离权重（拉满至100）
    int maxPriority = 0;

    for (const auto& target : allTargets) {
        // 只保留敌方、未倒地目标（基础过滤）
        if (!target.isEnemy || target.isKnocked) {
            continue;
        }

        // 计算玩家到目标头部的距离（优先锁定头部，距离拉满至2000）
        float targetDistance = Calculate3DDistance(
            player.posX, player.posY, player.posZ,
            target.headPosX, target.headPosY, target.headPosZ
        );
        if (targetDistance > config.maxLockDistance) {
            continue;
        }

        // 计算目标优先级（拉满各项权重，确保头部目标优先）
        int currentPriority = 0;
        // 部位优先级：头部+1000，躯干+500，四肢+100
        if (config.priorityPart == TargetPart::HEAD) {
            currentPriority += PART_WEIGHT;
        } else if (config.priorityPart == TargetPart::BODY) {
            currentPriority += PART_WEIGHT / 2;
        } else {
            currentPriority += PART_WEIGHT / 10;
        }
        // 低血优先级：所有目标（阈值100）均+500
        if (target.health <= config.lowHpThreshold) {
            currentPriority += LOWHP_WEIGHT;
        }
        // 距离优先级：距离越近加分越多（拉满权重）
        currentPriority += static_cast<int>(DISTANCE_WEIGHT / (targetDistance / 100 + 1));

        // 更新最高优先级目标（同优先级选最近）
        if (currentPriority > maxPriority || 
            (currentPriority == maxPriority && targetDistance < minDistance)) {
            maxPriority = currentPriority;
            minDistance = targetDistance;
            lockedTarget = target;
            foundValidTarget = true;
            outLockedPart = config.priorityPart; // 记录锁定部位
        }
    }

    if (!foundValidTarget) {
        return false;
    }

    // 步骤3：瞄准预测（拉满子弹速度，减少预判误差；室内无削弱）
    float bulletFlightTime = minDistance / config.bulletSpeed; // 子弹速度5000，飞行时间极短
    float predictedHeadX = lockedTarget.headPosX + (lockedTarget.moveSpeed * lockedTarget.moveDirX * bulletFlightTime);
    float predictedHeadY = lockedTarget.headPosY + (lockedTarget.moveSpeed * lockedTarget.moveDirY * bulletFlightTime);
    float predictedHeadZ = lockedTarget.headPosZ;

    // 室内场景无削弱（原0.7倍修正取消，保持100%预测）
    if (player.isIndoor) {
        predictedHeadX = lockedTarget.headPosX + (predictedHeadX - lockedTarget.headPosX) * 1.0f;
        predictedHeadY = lockedTarget.headPosY + (predictedHeadY - lockedTarget.headPosY) * 1.0f;
    }

    // 步骤4：自瞄强度计算（拉满至1.5，移动时额外增强）
    float aimStrength = config.aimStrengthMax; // 基础强度拉满1.5
    // 移动时强度再增强50%（原10%，拉满至50%）
    if (player.isMoving) {
        aimStrength *= 1.5f;
    }
    // 手动输入弱（默认0.1），不降低强度（原>1.0才降，此处无需处理）
    if (player.aimInput > 1.5f) {
        aimStrength *= 0.8f; // 仅极强输入时轻微降低（原0.5，拉满至0.8）
    }

    // 步骤5：计算最终瞄准角度（基于头部预测位置，瞬间锁定）
    float dirX = predictedHeadX - player.posX;
    float dirY = predictedHeadY - player.posY;
    float dirZ = predictedHeadZ - player.posZ;

    // 角度计算（保留高精度，确保锁定精准）
    float targetAngleX = atan2(dirY, dirX) * (180.0f / M_PI);
    float targetAngleY = asin(dirZ / minDistance) * (180.0f / M_PI);

    // 步骤6：应用瞄准平滑（拉满至0=瞬间锁定，无延迟）
    outAimAngleX = targetAngleX; // 直接赋值，无平滑延迟
    outAimAngleY = targetAngleY;

    return true;
}

// 5. 测试用例（所有测试数据拉满）
int main() {
    // 玩家数据：移动中、室外、弱手动输入（触发强度增强）
    PlayerData player = {
        0.0f, 0.0f, 0.0f,  // 玩家坐标(0,0,0)
        0.1f,               // 手动输入弱（0.1）
        false,              // 室外场景
        true                // 移动状态
    };

    // 目标数据：3个敌方，移动速度拉满15，头部坐标明确
    std::vector<TargetData> targets = {
        // 目标1：低血（10）、头部坐标(1800, 1200, 8)、移动速度15
        {101, 1800.0f, 1200.0f, 5.0f, 1800.0f, 1200.0f, 8.0f, 10.0f, true, false, 15.0f, 0.8f, 0.6f},
        // 目标2：满血（100）、头部坐标(1500, 900, 8)、移动速度15
        {102, 1500.0f, 900.0f, 5.0f, 1500.0f, 900.0f, 8.0f, 100.0f, true, false, 15.0f, -0.3f, 0.4f},
        // 目标3：低血（5）、头部坐标(2000, 1600, 8)、移动速度15（刚好在最大锁定距离）
        {103, 2000.0f, 1600.0f, 5.0f, 2000.0f, 1600.0f, 8.0f, 5.0f, true, false, 15.0f, 0.5f, -0.2f}
    };

    // 自瞄配置：所有参数拉满
    AimBotConfig aimConfig;
    aimConfig.maxLockDistance = 2000.0f;
    aimConfig.targetLostDelay = 5.0f;
    aimConfig.baseSmoothness = 0.0f;
    aimConfig.lowHpThreshold = 100.0f;
    aimConfig.bulletSpeed = 5000.0f;
    aimConfig.aimStrengthMax = 1.5f;

    // 初始化瞄准角度和锁定部位
    float currentAimX = 0.0f;
    float currentAimY = 0.0f;
    TargetPart lockedPart = TargetPart::BODY;

    // 执行自瞄逻辑
    bool isLocked = RunAimBot(player, targets, aimConfig, currentAimX, currentAimY, lockedPart);

    // 输出结果（展示拉满效果）
    if (isLocked) {
        std::cout << "✅ 自瞄锁定成功（所有数值拉满）！" << std::endl;
        std::cout << "锁定部位：" << (lockedPart == TargetPart::HEAD ? "头部" : lockedPart == TargetPart::BODY ? "躯干" : "四肢") << std::endl;
        std::cout << "最终瞄准角度：X=" << currentAimX << "°，Y=" << currentAimY << "°" << std::endl;
        std::cout << "生效配置：锁定距离2000单位 | 丢失延迟5秒 | 瞬间锁定 | 头部优先" << std::endl;
    } else {
        std::cout << "❌ 未找到有效目标，自瞄未激活" << std::endl;
    }

    return 0;
}