use crate::entity::{Entity, EntityState};
use crate::math::{Vec2, Vec3, Matrix4x4};
use bitflags::bitflags;
use serde::{Serialize, Deserialize};
use std::f32::consts::PI;

#[repr(C)]
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct AimTarget {
    pub entity_id: u32,
    pub head_pos: Vec3,
    pub body_pos: Vec3,
    pub distance: f32,
    pub fov: f32,
    pub priority: f32,
    pub visible: bool,
    pub last_seen_time: f32,
    pub prediction_ticks: u8,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct AimConfig {
    pub enabled: bool,
    pub auto_shoot: bool,
    pub smooth_aim: bool,
    pub prediction: bool,
    pub gravity_compensation: bool,
    pub auto_wall: bool,
    pub team_check: bool,
    pub anti_recoil: bool,
    pub triggerbot: bool,
    pub rapid_fire: bool,
    pub auto_scope: bool,
    pub advanced_prediction: bool,
    pub movement_compensation: bool,

    pub smooth_factor: f32,
    pub max_distance: f32,
    pub fov_radius: f32,
    pub recoil_control: f32,
    pub trigger_delay: u32,
    pub rapid_fire_interval: u32,
    pub zoom_multiplier: f32,
    pub aim_offset_x: f32,
    pub aim_offset_y: f32,
    pub aim_curve_strength: f32,
    pub aim_jitter_suppression: f32,
    pub aim_prediction_factor: f32,
    pub bullet_velocity: f32,
    pub bullet_gravity: f32,
    pub server_latency: f32,
    pub client_latency: f32,
    pub network_smoothing: f32,
    pub interpolation_factor: f32,
    pub extrapolation_limit: f32,
    pub aim_stickiness: f32,
    pub aim_drift_compensation: f32,

    pub aim_key: u32,
    pub aim_bone: AimBone,
    pub aim_priority_mode: AimPriorityMode,
    pub aim_visualization: AimVisualization,
    pub aim_method: AimMethod,
    pub smoothing_algorithm: SmoothingAlgorithm,
    pub detection_zone: DetectionZone,

    pub draw_fov: bool,
    pub draw_target_info: bool,
    pub aim_sound_alert: bool,
    pub aim_log: bool,

    pub disable_conditions: DisableConditions,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum AimBone {
    Head,
    Neck,
    Chest,
    Pelvis,
    ShoulderLeft,
    ShoulderRight,
    ElbowLeft,
    ElbowRight,
    WristLeft,
    WristRight,
    HipLeft,
    HipRight,
    KneeLeft,
    KneeRight,
    AnkleLeft,
    AnkleRight,
    FootLeft,
    FootRight,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum AimPriorityMode {
    Distance,
    ThreatLevel,
    VisibleOnly,
    ClosestToCrosshair,
    HighestScore,
    LowestHealth,
    MostRecentSpawn,
    Random,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum AimVisualization {
    None,
    Crosshair,
    TargetMarker,
    TextOverlay,
    LineToTarget,
    HitboxOutline,
    BoundingBox,
    HealthBar,
    NameTag,
    DistanceLabel,
    FOVCircle,
    PredictionLine,
    BulletPath,
    TrajectoryArc,
    Reticle,
    ScopeOverlay,
    HitMarker,
    DamageIndicator,
    BulletTracer,
    ExplosiveIndicator,
    GrenadeTrajectory,
    ObjectiveMarker,
    SafeZoneIndicator,
    DangerZoneIndicator,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum AimMethod {
    LinearInterpolation,
    SplineInterpolation,
    InstantSnap,
    BezierCurve,
    ExponentialSmoothing,
    KalmanFilter,
    PIDController,
    LeadPrediction,
    TrajectorySimulation,
    PredictiveTracking,
    AdaptiveSmoothing,
    VelocityMatching,
    WeaponSpecificAim,
    EnvironmentalAwarenessAim,
    TacticalPositioningAim,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum SmoothingAlgorithm {
    Linear,
    Bezier,
    CatmullRom,
    Exponential,
    MovingAverage,
    GaussianFilter,
    MedianFilter,
    Kalman,
    PID,
    SavitzkyGolay,
    ExponentialMovingAverage,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum DetectionZone {
    ScreenCenter,
    FullScreen,
    CrosshairArea,
    CustomFOV,
    TargetBoundingBox,
}

bitflags! {
    #[derive(Serialize, Deserialize)]
    pub struct DisableConditions: u64 {
        const ON_GUI = 1 << 0;
        const ON_MENU = 1 << 1;
        const ON_CHAT = 1 << 2;
        const ON_TYPING = 1 << 3;

        const ON_MOVEMENT = 1 << 4;
        const ON_JUMP = 1 << 5;
        const ON_CROUCH = 1 << 6;
        const ON_PRONE = 1 << 7;
        const ON_RELOAD = 1 << 8;
        const ON_GRENADE = 1 << 9;
        const ON_MELEE = 1 << 10;
        const ON_USE = 1 << 11;

        const ON_FLASHBANG = 1 << 12;
        const ON_SMOKE = 1 << 13;
        const ON_FIRE = 1 << 14;
        const ON_WATER = 1 << 15;

        const ON_LAVA = 1 << 16;
        const ON_ACID = 1 << 17;
        const ON_ELECTRIFIED = 1 << 18;
        const ON_MAGNETIC = 1 << 19;
        const ON_GRAVITY_WELL = 1 << 20;
        const ON_TIME_WARP = 1 << 21;
        const ON_STEALTH_ZONE = 1 << 22;
        const ON_EMP_ZONE = 1 << 23;

        const ON_SNIPER = 1 << 24;
        const ON_MACHINE_GUNNER = 1 << 25;
        const ON_SHOTGUNNER = 1 << 26;
        const ON_MEDIC = 1 << 27;
        const ON_ENGINEER = 1 << 28;
        const ON_ELITE_UNIT = 1 << 29;
        const ON_BOSS = 1 << 30;
    }
}

impl AimConfig {
    pub fn should_disable(&self, entity: &Entity) -> bool {
        if self.disable_conditions.contains(DisableConditions::ON_GUI) && self.disable_on_gui() {
            return true;
        }
        if entity.is_flashed && self.disable_conditions.contains(DisableConditions::ON_FLASHBANG) {
            return true;
        }
        false
    }

    #[inline]
    pub fn disable_on_gui(&self) -> bool {
        self.disable_conditions.contains(DisableConditions::ON_GUI)
    }
}



//禁止二改冷淡独家冷淡QQ群：849961629
//禁止二改冷淡独家冷淡QQ群：849961629
//禁止二改冷淡独家冷淡QQ群：849961629
//禁止二改冷淡独家冷淡QQ群：849961629
//禁止二改冷淡独家冷淡QQ群：849961629