//! 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 std::sync::Arc;

#[cfg(feature = "auth")]
use crate::auth::{AuthService, JwtService};
#[cfg(feature = "content-db")]
use crate::content::ContentService;
#[cfg(any(feature = "auth", feature = "content-db"))]
use crate::database;
#[cfg(feature = "email")]
use crate::email::EmailService;
#[cfg(feature = "metrics")]
use crate::metrics;
use crate::run::SiteOptions;
use crate::security::{csrf::CsrfState, rate_limit::RateLimiter};

/// 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 site_options: SiteOptions,

    /// 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>,

    /// Per-post engagement repository (views/ratings/messages, feature-gated)
    #[cfg(feature = "post-engagement")]
    pub engagement_repository: Arc<crate::database::engagement::EngagementRepository>,

    /// 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>>,

    /// Shared, hot-reloadable file RBAC config (optional, feature-gated)
    #[cfg(feature = "rbac")]
    pub file_rbac_config: Arc<tokio::sync::RwLock<crate::rbac::file_config::FileRbacConfig>>,

    /// WebSocket server for real-time notifications (RBAC sync, content
    /// updates)
    pub ws_server: Arc<crate::content::websocket::WebSocketServer>,

    /// NATS admin client for the operational bus (optional, feature-gated)
    #[cfg(feature = "nats-admin")]
    pub nats_client: Option<Arc<crate::nats::NatsAdminClient>>,
}

impl AppState {
    /// Create a new AppState instance
    ///
    /// This is typically called from the server startup process with all
    /// the required services properly initialized.
    #[allow(clippy::too_many_arguments)] // aggregating constructor for all shared services
    pub fn new(
        site_options: SiteOptions,
        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 = "post-engagement")] engagement_repository: Arc<
            crate::database::engagement::EngagementRepository,
        >,
        #[cfg(feature = "content-db")] content_service: Arc<ContentService>,
        #[cfg(feature = "email")] email_service: Arc<EmailService>,
        #[cfg(feature = "metrics")] metrics_registry: Option<Arc<metrics::MetricsRegistry>>,
        #[cfg(feature = "rbac")] file_rbac_config: Arc<
            tokio::sync::RwLock<crate::rbac::file_config::FileRbacConfig>,
        >,
        ws_server: Arc<crate::content::websocket::WebSocketServer>,
        #[cfg(feature = "nats-admin")] nats_client: Option<Arc<crate::nats::NatsAdminClient>>,
    ) -> Self {
        Self {
            site_options,
            csrf_state,
            rate_limiter,
            #[cfg(feature = "auth")]
            auth_service,
            #[cfg(feature = "auth")]
            jwt_service,
            #[cfg(feature = "auth")]
            auth_repository,
            #[cfg(feature = "post-engagement")]
            engagement_repository,
            #[cfg(feature = "content-db")]
            content_service,
            #[cfg(feature = "email")]
            email_service,
            #[cfg(feature = "metrics")]
            metrics_registry,
            #[cfg(feature = "rbac")]
            file_rbac_config,
            ws_server,
            #[cfg(feature = "nats-admin")]
            nats_client,
        }
    }
}
