use leptos::prelude::*;
use rustelo_core_lib::config::{AppConfig, LegalConfig, LogoConfig};

#[derive(Clone)]
pub struct ConfigContext {
    pub config: Memo<AppConfig>,
}

impl ConfigContext {
    /// Get legal configuration
    pub fn legal(&self) -> LegalConfig {
        self.config.get_untracked().legal
    }

    /// Get legal configuration (reactive)
    pub fn legal_reactive(&self) -> impl Fn() -> LegalConfig + Clone {
        let config = self.config;
        move || config.get().legal.clone()
    }

    /// Get logo configuration
    pub fn logo(&self) -> LogoConfig {
        self.config.get_untracked().logo
    }

    /// Get logo configuration (reactive)
    pub fn logo_reactive(&self) -> impl Fn() -> LogoConfig + Clone {
        let config = self.config;
        move || config.get().logo.clone()
    }
}

#[component]
pub fn ConfigProvider(children: leptos::prelude::Children) -> impl IntoView {
    // Load configuration safely for SSR and client contexts
    let config = Memo::new(move |_| {
        // Always use explicit hardcoded logo paths to ensure SSR/client consistency
        // These should match the values in .env file to avoid hydration mismatches
        AppConfig {
            logo: LogoConfig {
                light_path: String::from(""),
                dark_path: String::from(""),
                icon_path: String::from(""),
            },
            ..Default::default()
        }
    });

    let context = ConfigContext { config };

    provide_context(context);

    view! {
      {children()}
    }
}

#[derive(Clone)]
pub struct UseConfig(pub ConfigContext);

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

impl UseConfig {
    pub fn new() -> Self {
        Self(expect_context::<ConfigContext>())
    }

    /// Get legal configuration
    pub fn legal(&self) -> LegalConfig {
        self.0.legal()
    }

    /// Get legal configuration (reactive)
    pub fn legal_reactive(&self) -> impl Fn() -> LegalConfig + Clone {
        self.0.legal_reactive()
    }

    /// Get logo configuration
    pub fn logo(&self) -> LogoConfig {
        self.0.logo()
    }

    /// Get logo configuration (reactive)
    pub fn logo_reactive(&self) -> impl Fn() -> LogoConfig + Clone {
        self.0.logo_reactive()
    }

    /// Get contact email
    pub fn contact_email(&self) -> String {
        self.0.config.get_untracked().legal.contact_email
    }
}

/// Hook to use configuration
pub fn use_config() -> UseConfig {
    UseConfig::new()
}
