use crate::entity::Entity;
use crate::math::{Vec2, Vec3, Ray, RaycastResult};
use crate::aim::{AimConfig, AimTarget, AimBone};
use crate::bullet_tracer::BulletTracer;
use crate::auto_aim::AutoAim;
use std::f32::consts::PI;

#[derive(Clone, Debug, Default)]
pub struct ScopeAim {
    pub auto_aim: AutoAim,
    pub scope_active: bool,
    pub scope_zoom: f32,
    pub perfect_accuracy: bool,
    pub no_spread: bool,
    pub no_recoil: bool,
    pub no_sway: bool,
    pub instant_hitscan: bool,
    pub max_scope_distance: f32,
}

impl ScopeAim {
    pub fn new(config: AimConfig) -> Self {
        Self {
            auto_aim: AutoAim::new(config),
            scope_zoom: 4.0,
            perfect_accuracy: true,
            no_spread: true,
            no_recoil: true,
            no_sway: true,
            instant_hitscan: true,
            max_scope_distance: 1500.0,
            ..Self::default()
        }
    }

    fn toggle_scope(&mut self, enable: bool) {
        self.scope_active = enable;
        if self.scope_active {
            self.auto_aim.config.fov_radius /= self.scope_zoom;
            self.auto_aim.config.max_distance = self.max_scope_distance;
        } else {
            self.auto_aim.config.fov_radius *= self.scope_zoom;
            self.auto_aim.config.max_distance = self.auto_aim.bullet_tracer.max_trace_distance;
        }
    }

    fn apply_perfect_accuracy(&self, angles: Vec2) -> Vec2 {
        if self.perfect_accuracy {
            angles
        } else {
            self.apply_spread_compensation(angles)
        }
    }

    fn apply_spread_compensation(&self, angles: Vec2) -> Vec2 {
        if self.no_spread {
            return angles;
        }
        let spread = 0.01;
        Vec2::new(
            angles.x + (rand::random::<f32>() - 0.5) * spread,
            angles.y + (rand::random::<f32>() - 0.5) * spread,
        )
    }

    fn apply_recoil_override(&self, angles: Vec2) -> Vec2 {
        if self.no_recoil {
            angles
        } else {
            self.auto_aim.apply_recoil_compensation(angles)
        }
    }

    fn apply_sway_override(&self, angles: Vec2) -> Vec2 {
        if self.no_sway {
            angles
        } else {
            let sway = 0.005;
            Vec2::new(
                angles.x + (rand::random::<f32>() - 0.5) * sway,
                angles.y + (rand::random::<f32>() - 0.5) * sway,
            )
        }
    }

    fn instant_hit(&self, shooter_pos: Vec3, target_pos: Vec3) -> bool {
        if !self.instant_hitscan {
            return false;
        }
        let ray = Ray::new(shooter_pos, (target_pos - shooter_pos).normalize());
        ray.cast(self.max_scope_distance, 0.001)
            .map_or(false, |r| r.obstacle_type == ObstacleType::Entity)
    }

    pub fn update(
        &mut self,
        local_entity: &Entity,
        entities: &[Entity],
        view_matrix: &Matrix4x4,
        screen_width: f32,
        screen_height: f32,
        delta_time: f32,
        scope_key_pressed: bool,
    ) -> Option<Vec2> {
        self.toggle_scope(scope_key_pressed);
        
        if !self.auto_aim.config.enabled || !self.scope_active {
            return None;
        }

        let mut aim_angles = self.auto_aim.update(
            local_entity,
            entities,
            view_matrix,
            screen_width / self.scope_zoom,
            screen_height / self.scope_zoom,
            delta_time,
        )?;

        aim_angles = self.apply_perfect_accuracy(aim_angles);
        aim_angles = self.apply_recoil_override(aim_angles);
        aim_angles = self.apply_sway_override(aim_angles);

        if self.instant_hitscan && self.auto_aim.current_target.is_some() {
            let target = entities.iter()
                .find(|e| e.id == self.auto_aim.current_target.unwrap())?;
            if self.instant_hit(local_entity.pos, target.head_pos) {
                self.auto_aim.auto_shoot();
            }
        }

        Some(aim_angles)
    }

    pub fn draw_scope(&self, screen_width: f32, screen_height: f32, color: [f32; 4]) {
        if self.scope_active {
            let center = Vec2::new(screen_width / 2.0, screen_height / 2.0);
            let crosshair_size = 10.0 / self.scope_zoom;
        }
    }
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ObstacleType {
    None,
    Entity,
    Wall,
    Ground,
    Water,
    Glass,
}




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