//! `mission_executor` — multirotor + fixed-wing FSMs, geofence, failsafe.
//!
//! Real implementation lands in:
//! - AZ-648 `mission_executor_state_machine`
//! - AZ-649 `mission_executor_telemetry_forwarding`
//! - AZ-650 `mission_executor_bit_f9`
//! - AZ-651 `mission_executor_lost_link_ladder`
//! - AZ-652 `mission_executor_safety_and_resume`

use serde::{Deserialize, Serialize};

use shared::error::{AutopilotError, Result};
use shared::health::ComponentHealth;
use shared::models::mission::{Coordinate, MissionItem};

const NAME: &str = "mission_executor";

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum ExecutorState {
    Disconnected,
    PreFlight,
    Taxi,
    Climb,
    Cruise,
    MiddleWaypointInsert,
    TargetFollow,
    Rtl,
    Land,
    WaitAuto,
    Aborted,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum FailsafeKind {
    LinkDegraded,
    LinkLost,
    LinkLostInFollow,
    BatteryRtl,
    BatteryHardFloor,
    GeofenceInclusion,
    GeofenceExclusion,
}

pub struct MissionExecutor;

impl MissionExecutor {
    pub fn new() -> Self {
        Self
    }

    pub fn handle(&self) -> MissionExecutorHandle {
        MissionExecutorHandle
    }
}

impl Default for MissionExecutor {
    fn default() -> Self {
        Self::new()
    }
}

#[derive(Clone, Copy)]
pub struct MissionExecutorHandle;

impl MissionExecutorHandle {
    pub async fn start(&self, _mission: Vec<MissionItem>) -> Result<()> {
        Err(AutopilotError::NotImplemented(
            "mission_executor::start (AZ-648)",
        ))
    }

    pub async fn insert_middle_waypoint(&self, _at: Coordinate) -> Result<()> {
        Err(AutopilotError::NotImplemented(
            "mission_executor::insert_middle_waypoint (AZ-652)",
        ))
    }

    pub async fn failsafe_trigger(&self, _kind: FailsafeKind) -> Result<()> {
        Err(AutopilotError::NotImplemented(
            "mission_executor::failsafe_trigger (AZ-651)",
        ))
    }

    pub fn state(&self) -> ExecutorState {
        ExecutorState::Disconnected
    }

    pub fn health(&self) -> ComponentHealth {
        ComponentHealth::disabled(NAME)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_compiles() {
        let h = MissionExecutor::new().handle();
        assert_eq!(h.state(), ExecutorState::Disconnected);
        assert_eq!(h.health().level, shared::health::HealthLevel::Disabled);
    }
}
