//! Content kinds configuration loading with NCL and TOML support
//!
//! This module provides typed loading of content-kinds configuration from both
//! Nickel (.ncl) and TOML (.toml) formats. NCL is preferred for its type safety
//! and defaults, with TOML as a fallback for backward compatibility.
//!
//! # Architecture
//!
//! - Uses `rustelo_tools::ContentKindConfig` types (no duplication)
//! - Delegates NCL processing to `rustelo_config`
//! - Auto-detects format: tries .ncl first, falls back to .toml
//!
//! # Examples
//!
//! ```no_run
//! use build_config::content_kind_config;
//! use std::path::Path;
//!
//! // Load from NCL (preferred) or TOML (fallback)
//! let content_kinds = content_kind_config::load_content_kinds(
//!     Path::new("site/content")
//! )?;
//!
//! for kind in content_kinds {
//!     println!("Content type: {}", kind.name);
//!     println!("  Directory: {}", kind.directory);
//!     println!("  Enabled: {}", kind.enabled);
//! }
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```

use std::fs;
use std::path::Path;

use anyhow::anyhow;

// Re-export types from rustelo_tools (single source of truth)
pub use rustelo_tools::build::build_tasks::content_types::{
    ContentFeatures, ContentKindConfig, ContentKindsConfig,
};

use crate::Result;

/// Load content kinds from a TOML file
///
/// # Arguments
///
/// * `path` - Path to content-kinds.toml file
///
/// # Returns
///
/// Vector of `ContentKindConfig` structs
///
/// # Errors
///
/// Returns error if:
/// - File cannot be read
/// - TOML parsing fails
/// - Required fields are missing
///
/// # Examples
///
/// ```no_run
/// use build_config::content_kind_config;
/// use std::path::Path;
///
/// let kinds = content_kind_config::load_content_kinds_from_toml(
///     Path::new("site/content/content-kinds.toml")
/// )?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
pub fn load_content_kinds_from_toml(path: &Path) -> Result<Vec<ContentKindConfig>> {
    let content = fs::read_to_string(path)?;
    let config: ContentKindsConfig = toml::from_str(&content)?;
    Ok(config.content_kinds)
}

/// Load content kinds from a Nickel file
///
/// Uses `rustelo_config` to export NCL to JSON, then deserializes to typed structs.
/// This provides type safety and validation at configuration time.
///
/// # Arguments
///
/// * `path` - Path to content-kinds.ncl file
///
/// # Returns
///
/// Vector of `ContentKindConfig` structs
///
/// # Errors
///
/// Returns error if:
/// - Nickel export fails (nickel CLI not available, syntax errors, type errors)
/// - JSON parsing fails
/// - Required fields are missing
///
/// # Examples
///
/// ```no_run
/// use build_config::content_kind_config;
/// use std::path::Path;
///
/// let kinds = content_kind_config::load_content_kinds_from_ncl(
///     Path::new("site/content/content-kinds.ncl")
/// )?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
pub fn load_content_kinds_from_ncl(path: &Path) -> Result<Vec<ContentKindConfig>> {
    // Use rustelo_config to export NCL to JSON
    let json_output = rustelo_config::nickel::export_to_json(path)?;

    // Parse JSON into typed structs
    let config: ContentKindsConfig = serde_json::from_str(&json_output)?;

    Ok(config.content_kinds)
}

/// Load content kinds with automatic format detection
///
/// Tries to load from content-kinds.ncl first (preferred), falls back to
/// content-kinds.toml if NCL file doesn't exist or nickel CLI is unavailable.
///
/// # NCL-First Strategy
///
/// 1. Check if `{content_dir}/content-kinds.ncl` exists
/// 2. If yes, try to load via NCL (with schema validation)
/// 3. If NCL fails (CLI missing, syntax error), fall back to TOML
/// 4. If no NCL file, load from TOML directly
///
/// # Arguments
///
/// * `content_dir` - Directory containing content-kinds configuration
///
/// # Returns
///
/// Vector of `ContentKindConfig` structs
///
/// # Errors
///
/// Returns error only if both NCL and TOML loading fail
///
/// # Examples
///
/// ```no_run
/// use build_config::content_kind_config;
/// use std::path::Path;
///
/// // Tries content-kinds.ncl first, falls back to content-kinds.toml
/// let kinds = content_kind_config::load_content_kinds(
///     Path::new("site/content")
/// )?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
pub fn load_content_kinds(content_dir: &Path) -> Result<Vec<ContentKindConfig>> {
    let ncl_path = content_dir.join("content-kinds.ncl");
    let toml_path = content_dir.join("content-kinds.toml");

    // Try NCL first (preferred)
    if ncl_path.exists() {
        match load_content_kinds_from_ncl(&ncl_path) {
            Ok(kinds) => {
                println!("cargo:warning=Loaded content kinds from NCL (with type validation)");
                return Ok(kinds);
            }
            Err(e) => {
                println!(
                    "cargo:warning=NCL loading failed ({}), falling back to TOML",
                    e
                );
                // Fall through to TOML
            }
        }
    }

    // Fall back to TOML
    if toml_path.exists() {
        let kinds = load_content_kinds_from_toml(&toml_path)?;
        println!("cargo:warning=Loaded content kinds from TOML (fallback)");
        Ok(kinds)
    } else {
        Err(anyhow!(
            "No content kinds configuration found (tried {} and {})",
            ncl_path.display(),
            toml_path.display()
        ))
    }
}

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

    #[test]
    fn test_load_from_toml() {
        // This would require a test fixture
        // For now, just verify types are importable
        let _config = ContentKindsConfig {
            content_kinds: vec![],
        };
    }

    #[test]
    fn test_content_kind_structure() {
        // Verify we can construct the types
        let _features = ContentFeatures {
            style_mode: "row".to_string(),
            style_css: "test-content".to_string(),
            use_feature: true,
            use_categories: true,
            use_tags: true,
            use_emojis: false,
            cta_view: "DefaultCTAView".to_string(),
            default_page_size: Some(12),
            page_size_options: Some(vec![6, 12, 24]),
            show_page_info: Some(true),
            pagination_style: Some("numbered".to_string()),
            show_difficulty: None,
            show_duration: None,
            show_prerequisites: None,
        };

        let _kind = ContentKindConfig {
            name: "blog".to_string(),
            directory: "blog".to_string(),
            enabled: true,
            is_default: Some(false),
            specialized: Some(false),
            features: _features,
        };
    }
}
