//! Application State Module
//!
//! Unified application state that works with Axum's single-state requirement.
//! This module contains the AppState struct and related functionality for managing
//! shared application services and configuration.

use crate::security::{csrf::CsrfState, rate_limit::RateLimiter};
use leptos::prelude::*;
#[cfg(any(
    feature = "auth",
    feature = "content-db",
    feature = "email",
    feature = "metrics"
))]
use std::sync::Arc;

#[cfg(feature = "auth")]
use auth::{AuthService, JwtService};

#[cfg(feature = "content-db")]
use content::ContentService;

#[cfg(any(feature = "auth", feature = "content-db"))]
use database;

#[cfg(feature = "email")]
use email::EmailService;

#[cfg(feature = "metrics")]
use metrics;

/// Unified application state that works with Axum's single-state requirement
///
/// This struct contains all the shared services and configuration needed
/// across the application. It's designed to be cloned efficiently and
/// passed to Axum route handlers.
#[derive(Clone)]
pub struct AppState {
    /// Leptos configuration options for SSR
    pub leptos_options: LeptosOptions,

    /// CSRF protection state
    pub csrf_state: CsrfState,

    /// Rate limiting service
    pub rate_limiter: RateLimiter,

    /// Authentication service (optional, feature-gated)
    #[cfg(feature = "auth")]
    pub auth_service: Arc<AuthService>,

    /// JWT token service (optional, feature-gated)
    #[cfg(feature = "auth")]
    pub jwt_service: Arc<JwtService>,

    /// Authentication repository (optional, feature-gated)
    #[cfg(feature = "auth")]
    pub auth_repository: Arc<database::auth::AuthRepository>,

    /// Content management service (optional, feature-gated)
    #[cfg(feature = "content-db")]
    pub content_service: Arc<ContentService>,

    /// Email service (optional, feature-gated)
    #[cfg(feature = "email")]
    pub email_service: Arc<EmailService>,

    /// Metrics registry (optional, feature-gated)
    #[cfg(feature = "metrics")]
    pub metrics_registry: Option<Arc<metrics::MetricsRegistry>>,
}

impl AppState {
    /// Create a new AppState instance
    ///
    /// This is typically called from the server startup process with all
    /// the required services properly initialized.
    pub fn new(
        leptos_options: LeptosOptions,
        csrf_state: CsrfState,
        rate_limiter: RateLimiter,
        #[cfg(feature = "auth")] auth_service: Arc<AuthService>,
        #[cfg(feature = "auth")] jwt_service: Arc<JwtService>,
        #[cfg(feature = "auth")] auth_repository: Arc<database::auth::AuthRepository>,
        #[cfg(feature = "content-db")] content_service: Arc<ContentService>,
        #[cfg(feature = "email")] email_service: Arc<EmailService>,
        #[cfg(feature = "metrics")] metrics_registry: Option<Arc<metrics::MetricsRegistry>>,
    ) -> Self {
        Self {
            leptos_options,
            csrf_state,
            rate_limiter,
            #[cfg(feature = "auth")]
            auth_service,
            #[cfg(feature = "auth")]
            jwt_service,
            #[cfg(feature = "auth")]
            auth_repository,
            #[cfg(feature = "content-db")]
            content_service,
            #[cfg(feature = "email")]
            email_service,
            #[cfg(feature = "metrics")]
            metrics_registry,
        }
    }
}
