use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// All user-facing messages for provctl, loaded from TOML.
///
/// This struct ensures that NO hardcoded strings exist in the codebase.
/// All messages come from configuration files, making the tool fully
/// localizable and configurable.
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct Messages {
    /// Service start operation messages
    pub service_start: ServiceStartMessages,

    /// Service stop operation messages
    pub service_stop: ServiceStopMessages,

    /// Service status operation messages
    pub service_status: ServiceStatusMessages,

    /// Error messages
    pub errors: ErrorMessages,

    /// General/help messages
    pub general: GeneralMessages,
}

/// Messages for service start operations.
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct ServiceStartMessages {
    /// Message shown when starting a service (uses {service_name} placeholder)
    pub starting: String,

    /// Message shown when service started successfully (uses {service_name}, {pid} placeholders)
    pub started: String,

    /// Message shown when start fails (uses {service_name}, {error} placeholders)
    pub failed: String,

    /// Message when service is already running (uses {service_name}, {pid} placeholders)
    pub already_running: String,
}

/// Messages for service stop operations.
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct ServiceStopMessages {
    /// Message shown when stopping a service (uses {service_name} placeholder)
    pub stopping: String,

    /// Message shown when service stopped successfully (uses {service_name} placeholder)
    pub stopped: String,

    /// Message when service is not running (uses {service_name} placeholder)
    pub not_running: String,

    /// Message when stop fails (uses {service_name}, {error} placeholders)
    pub failed: String,
}

/// Messages for service status queries.
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct ServiceStatusMessages {
    /// Format for running status (uses {service_name}, {pid} placeholders)
    pub running: String,

    /// Format for not running status (uses {service_name} placeholder)
    pub not_running: String,

    /// Format for unknown status (uses {service_name} placeholder)
    pub unknown: String,

    /// Message when fetching status fails (uses {service_name}, {error} placeholders)
    pub check_failed: String,
}

/// Error messages.
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct ErrorMessages {
    /// Service not found (uses {service_name} placeholder)
    pub service_not_found: String,

    /// Permission denied (uses {operation} placeholder)
    pub permission_denied: String,

    /// Configuration error (uses {path}, {reason} placeholders)
    pub config_error: String,

    /// Backend not available (uses {backend} placeholder)
    pub backend_not_available: String,
}

/// General and help messages.
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct GeneralMessages {
    /// Help text
    pub help: String,

    /// Version text
    pub version: String,

    /// Unknown command error
    pub unknown_command: String,
}

impl Messages {
    /// Formats a message with placeholders replaced.
    ///
    /// # Examples
    ///
    /// ```ignore
    /// let formatted = messages.format(
    ///     "Service {service_name} started with PID {pid}",
    ///     &[("service_name", "api"), ("pid", "1234")],
    /// );
    /// ```
    pub fn format(&self, template: &str, vars: &[(&str, &str)]) -> String {
        let mut result = template.to_string();
        for (key, value) in vars {
            let placeholder = format!("{{{}}}", key);
            result = result.replace(&placeholder, value);
        }
        result
    }
}

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

    #[test]
    fn test_message_formatting() {
        let messages = Messages::default();
        let formatted = messages.format(
            "Service {service_name} started with PID {pid}",
            &[("service_name", "api"), ("pid", "1234")],
        );
        assert_eq!(formatted, "Service api started with PID 1234");
    }

    #[test]
    fn test_message_formatting_single_var() {
        let messages = Messages::default();
        let formatted = messages.format("Service {name} is running", &[("name", "test")]);
        assert_eq!(formatted, "Service test is running");
    }

    #[test]
    fn test_message_formatting_no_vars() {
        let messages = Messages::default();
        let formatted = messages.format("All systems operational", &[]);
        assert_eq!(formatted, "All systems operational");
    }
}
