//! Fragment and include handling
//!
//! Provides logic for loading form fragments and expanding group includes.

use crate::error::Result;
use std::path::{Path, PathBuf};

use super::parser::{load_elements_from_file, resolve_constraints_in_content};
use super::types::{FormDefinition, FormElement};

/// Load a fragment form from file path (public API for backends)
///
/// Loads a TOML file containing a FormDefinition and migrates it to the unified format.
/// This is the public API used by backends (e.g., CLI RepeatingGroup) to load fragment forms.
///
/// # Arguments
/// * `path` - File path (relative or absolute)
///
/// # Returns
/// A FormDefinition with migrated elements
pub fn load_fragment_form(path: &str) -> Result<FormDefinition> {
    let content = std::fs::read_to_string(path)?;

    // Get the directory of the fragment file for constraint resolution
    let fragment_dir = PathBuf::from(path)
        .parent()
        .map(|p| p.to_path_buf())
        .unwrap_or_else(|| PathBuf::from("."));

    // Resolve constraint interpolations before parsing
    let resolved_content = resolve_constraints_in_content(&content, &fragment_dir)?;
    let mut form: FormDefinition = toml::from_str(&resolved_content)?;
    form.migrate_to_elements();
    Ok(form)
}

/// Expand groups with includes in a FormDefinition (for non-interactive use)
pub fn expand_includes(mut form: FormDefinition, base_dir: &Path) -> Result<FormDefinition> {
    let mut expanded_elements = Vec::new();

    // First migrate legacy format if necessary
    if form.elements.is_empty() && (!form.items.is_empty() || !form.fields.is_empty()) {
        form.migrate_to_elements();
    }

    // Process elements and expand any groups with includes
    for element in form.elements.iter() {
        if let FormElement::Item(item) = element {
            // Handle group type with includes
            if item.item_type == "group" {
                if let Some(includes) = &item.includes {
                    let group_condition = item.when.clone(); // Capture group's when condition

                    // Load elements from included files
                    for include_path in includes {
                        match load_elements_from_file(include_path, base_dir) {
                            Ok(mut loaded_elements) => {
                                // Propagate group's when condition to loaded elements if group has one
                                for element in loaded_elements.iter_mut() {
                                    if let Some(ref condition) = group_condition {
                                        if element.when().is_none() {
                                            match element {
                                                FormElement::Item(ref mut item) => {
                                                    item.when = Some(condition.clone())
                                                }
                                                FormElement::Field(ref mut field) => {
                                                    field.when = Some(condition.clone())
                                                }
                                            }
                                        }
                                    }
                                }
                                expanded_elements.extend(loaded_elements);
                            }
                            Err(e) => {
                                eprintln!(
                                    "⚠ Warning: Failed to load fragment '{}': {}",
                                    include_path, e
                                );
                            }
                        }
                    }
                }
            } else {
                // Non-group items are included as-is, maintaining their position and order
                expanded_elements.push(element.clone());
            }
        } else {
            // Fields and other elements pass through unchanged
            expanded_elements.push(element.clone());
        }
    }

    // Update form with expanded elements
    form.elements = expanded_elements;
    // Clear legacy arrays since we've expanded into elements
    form.items.clear();
    form.fields.clear();

    Ok(form)
}
