// retrigger-build-marker-6
// retrigger-build-marker-4
#![allow(dead_code)]

mod ai;
mod ai_credits;
mod ai_subscription;
mod handlers;
mod litellm;
mod mail;

use axum::{routing::get, Router};
use std::net::SocketAddr;
use std::sync::Arc;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
use sqlx::PgPool;
use mail::Mailer;

#[derive(Clone)]
pub struct AppState {
    pub pool:    PgPool,
    pub mail:    Arc<Mailer>,
    pub redis:   cache::RedisPool,
    pub storage: Arc<storage::StorageClient>,
}

#[tokio::main]
async fn main() {
    tracing_subscriber::registry()
        .with(tracing_subscriber::EnvFilter::new(
            std::env::var("RUST_LOG").unwrap_or_else(|_| "info".into()),
        ))
        .with(tracing_subscriber::fmt::layer())
        .init();

    // Fail fast — critical env vars must be present before binding any port
    std::env::var("JWT_SECRET").expect("JWT_SECRET must be set");

    let database_url =
        std::env::var("DATABASE_URL").expect("DATABASE_URL must be set");

    let pool = db::establish_connection(&database_url)
        .await
        .expect("Failed to connect to the database");

    tracing::info!("Connected to the database");

    let redis_url = std::env::var("REDIS_URL")
        .unwrap_or_else(|_| "redis://127.0.0.1:6379".to_string());
    let redis = cache::connect(&redis_url)
        .await
        .expect("Failed to connect to Redis");
    tracing::info!("Connected to Redis");

    let mailer = Arc::new(Mailer::new());

    let storage = Arc::new(storage::StorageClient::from_env().await);

    let state = AppState {
        pool,
        mail:    mailer,
        redis,
        storage,
    };

    let app = Router::new()
        // ── Auth ─────────────────────────────────────────────────────────
        .nest("/api/auth", handlers::auth::router())
        // ── V1 API (backward compatibility) ───────────────────────────────
        .nest("/api/v1/users", handlers::auth::v1_router())
        // ── Roles & User Self-Service ─────────────────────────────────────
        .nest("/api/admin/roles", handlers::roles::router())
        .nest("/api/admin/permissions", handlers::permissions::router())
        .nest("/api/admin/external-roles", handlers::external_roles::router())
        .merge(handlers::modules::persona_types_router())
        .merge(handlers::modules::modules_router())
        .merge(handlers::modules::role_modules_router())
        .nest("/api/admin/users", handlers::admin::router())
        .nest("/api/me/roles", handlers::user_roles::router())
        // ── Notifications ─────────────────────────────────────────────────
        .nest("/api/me/notifications", handlers::notifications::router())
        .nest("/api/me/settings", handlers::settings::router())
        // ── Admin: Approvals (jobs/requirements) ─────────────────────────
        .nest("/api/admin/approvals", handlers::approvals::router())
        .nest("/api/admin/verifications", handlers::verifications::router())
        // ── Me: Profile Status + Verification Status ──────────────────────
        .nest("/api/me", handlers::profile::me_router())
        // ── Profile (save + submit-for-verification) ──────────────────────
        .nest("/api/profile", handlers::profile::router())
        // ── Onboarding State (legacy, kept for compatibility) ────────────
        .nest("/api/onboarding", handlers::onboarding::onboarding_router())
        // ── Admin: Onboarding + Dashboard Config ──────────────────────────
        .nest("/api/admin/onboarding-config", handlers::config::onboarding_router())
        .nest("/api/admin/dashboard-config", handlers::config::dashboard_router())
        .nest("/api/admin/dashboard", handlers::dashboard::router())
        .nest("/api/admin/runtime-configs", handlers::config::admin_runtime_router())
        // ── Admin: Activity Logs (Audit) ───────────────────────────────────
        .nest("/api/admin/activity-logs", handlers::activity_logs::router())
        // ── Public Config ─────────────────────────────────────────────────
        .nest("/api/config/onboarding", handlers::config::onboarding_router())
        .nest("/api/config/dashboard", handlers::config::dashboard_router())
        .nest("/api/runtime-config", handlers::config::runtime_router())
        // ── Knowledge Base (public) ───────────────────────────────────────
        .nest("/api/kb", handlers::kb::public_router())
        // ── Knowledge Base (admin) ────────────────────────────────────────
        .nest("/api/admin/kb", handlers::kb::admin_router())
        // ── Support Tickets (user-facing) ─────────────────────────────────
        .nest("/api/support/tickets", handlers::support::user_router())
        // ── Support Tickets (admin) ───────────────────────────────────────
        .nest("/api/admin/support-cases", handlers::support::admin_router())
        // ── Reference number lookup (AI assistant) ────────────────────────
        .nest("/api/support", handlers::support::reference_router())
        // ── Reviews (public + admin) ─────────────────────────────────────
        .nest("/api/reviews", handlers::reviews::public_router())
        .nest("/api/admin/reviews", handlers::reviews::admin_router())
        // ── Coupons & Discounts (admin) ───────────────────────────────────
        .nest("/api/admin/coupons", handlers::coupons::coupons_router())
        .nest("/api/admin/discounts", handlers::coupons::discounts_router())
        .nest("/api/admin/payment-gateway-config", handlers::payment_gateway::router())
        // ── Tracecoin Packages (public) ───────────────────────────────────
        .nest("/api/packages", handlers::pricing::public_packages_router())
        // ── Tracecoin Packages & Reports (admin) ──────────────────────────
        .nest("/api/admin/tracecoin-packages", handlers::pricing::packages_router())
        .nest("/api/admin/reports", handlers::pricing::reports_router())
        // ── Email Management (admin) ──────────────────────────────────────
        .nest("/api/admin/email", handlers::admin_email::router())
        // ── AI Management (admin) ────────────────────────────────────────
        .nest("/api/admin/ai", handlers::admin_ai::admin_ai_router())
        // ── AI Assistant ──────────────────────────────────────────────────
        .nest("/api/ai", handlers::ai::ai_router())
        // ── Ask Ash AI Credits (Phase 1) ────────────────────────────────────
        .nest("/api/ai-credits", handlers::ai_credits::router())

        .nest("/internal/users", handlers::internal::router())
        .nest("/api/admin/ai-credits", handlers::ai_credits::admin_router())
        .route("/health", get(|| async { "Users OK" }))
        .with_state(state);


    let port: u16 = std::env::var("PORT")
        .unwrap_or_else(|_| "9101".to_string())
        .parse()
        .expect("PORT must be a valid u16");
    let addr = SocketAddr::from(([0, 0, 0, 0], port));

    tracing::info!("Users service listening on {}", addr);

    let listener = tokio::net::TcpListener::bind(&addr).await.unwrap();
    let _app = axum::serve(listener, app).await.unwrap();
}
