use std::sync::Arc;

use axum::extract::FromRef;
use leptos::get_configuration;

use crate::{config::Config, domain::api::ports::ApiService};

#[derive(Clone)]
/// The global application state shared between all request handlers.
pub struct AppState<S>
where
    S: ApiService,
{
    pub leptos_options: leptos::LeptosOptions,
    config: Arc<Config>,
    api_service: Arc<S>,
}

impl<S> AppState<S>
where
    S: ApiService,
{
    pub async fn new(api_service: S, config: Config) -> Self {
        Self {
            config: Arc::new(config),
            leptos_options: get_configuration(None).await.unwrap().leptos_options,
            api_service: Arc::new(api_service),
        }
    }

    pub fn config(&self) -> Arc<Config> {
        self.config.clone()
    }

    pub fn api_service(&self) -> Arc<S> {
        self.api_service.clone()
    }
}

impl<S> FromRef<AppState<S>> for leptos::LeptosOptions
where
    S: ApiService,
{
    fn from_ref(input: &AppState<S>) -> Self {
        input.leptos_options.clone()
    }
}
