//! Plan type definitions
//!
//! Plan represents a coarse-grained DAG description generated by LLM.

use serde::{Deserialize, Serialize};

use super::Step;

/// Execution plan - the primary asset of the system
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Plan {
    /// High-level goal description
    pub goal: String,
    /// Ordered list of steps to execute
    pub steps: Vec<Step>,
    /// Planning confidence (0.0 - 1.0)
    #[serde(default)]
    pub confidence: Option<f32>,
    /// User-facing message template on successful completion.
    /// Supports `{{step_id.export_key}}` placeholders resolved from WorkingSet.
    #[serde(default)]
    pub on_complete: Option<String>,
    /// User-facing message template on failure.
    #[serde(default)]
    pub on_failure: Option<String>,
}

impl Plan {
    /// Create a new plan
    pub fn new(goal: impl Into<String>, steps: Vec<Step>) -> Self {
        Self {
            goal: goal.into(),
            steps,
            confidence: None,
            on_complete: None,
            on_failure: None,
        }
    }

    /// Create a new plan with confidence
    pub fn with_confidence(goal: impl Into<String>, steps: Vec<Step>, confidence: f32) -> Self {
        Self {
            goal: goal.into(),
            steps,
            confidence: Some(confidence.clamp(0.0, 1.0)),
            on_complete: None,
            on_failure: None,
        }
    }

    /// Check if this is a high-confidence plan (>= 0.8)
    pub fn is_high_confidence(&self) -> bool {
        self.confidence.map(|c| c >= 0.8).unwrap_or(false)
    }

    /// Check if this is a low-confidence plan (< 0.5)
    pub fn is_low_confidence(&self) -> bool {
        self.confidence.map(|c| c < 0.5).unwrap_or(false)
    }

    /// Get step by ID
    pub fn get_step(&self, id: &str) -> Option<&Step> {
        self.steps.iter().find(|s| s.id.as_str() == id)
    }

    /// Get step IDs in order
    pub fn step_ids(&self) -> Vec<&str> {
        self.steps.iter().map(|s| s.id.as_str()).collect()
    }
}
