use crate::mesh::Vec3;

/// What phase a crawler is in.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Phase {
    /// Marching inward toward the object from the bounding sphere.
    Contact,
    /// Crawling along the surface to map boundaries.
    Patrol,
    /// Spiraling to identify face regions after a path crossing.
    Spiral,
    /// Raster-scanning a face ("mowing the lawn").
    Scan,
    /// Work complete, awaiting reassignment or termination.
    Done,
}

/// Per-crawler state. Each crawler is an independent agent.
/// On GPU, this maps to a storage buffer struct.
#[derive(Debug, Clone)]
pub struct Crawler {
    pub id: u32,
    pub phase: Phase,
    pub position: Vec3,
    pub direction: Vec3,
    pub normal: Vec3,
    pub face_id: u32,
    pub steps: u32,
    /// Spiral radius (grows each step in Spiral phase).
    pub spiral_r: f64,
    /// Spiral angle accumulator.
    pub spiral_theta: f64,
    /// Scan state: row origin and direction.
    pub scan_origin: Vec3,
    pub scan_dir: Vec3,
    pub scan_row: u32,
    pub scan_row_progress: f64,
    pub scan_row_length: f64,
}

impl Crawler {
    pub fn new_probe(id: u32, position: Vec3, direction: Vec3) -> Self {
        Self {
            id,
            phase: Phase::Contact,
            position,
            direction,
            normal: Vec3::zero(),
            face_id: 0,
            steps: 0,
            spiral_r: 0.0,
            spiral_theta: 0.0,
            scan_origin: Vec3::zero(),
            scan_dir: Vec3::zero(),
            scan_row: 0,
            scan_row_progress: 0.0,
            scan_row_length: 0.0,
        }
    }

    pub fn is_active(&self) -> bool {
        self.phase != Phase::Done
    }
}

/// Events emitted by crawlers during stepping.
#[derive(Debug)]
pub enum CrawlerEvent {
    /// Crawler hit the surface for the first time.
    ContactMade { crawler_id: u32, position: Vec3, normal: Vec3 },
    /// Two crawlers crossed paths.
    PathCrossing { crawler_a: u32, crawler_b: u32, position: Vec3 },
    /// Crawler identified a face boundary.
    FaceBoundary { crawler_id: u32, position: Vec3, normal_change: f64 },
    /// Surface sample recorded during scan phase.
    SampleRecorded { crawler_id: u32, position: Vec3, normal: Vec3, face_id: u32 },
    /// Crawler finished its work.
    Completed { crawler_id: u32 },
}
