use axum::{
    response::Json,
    routing::{delete, get, post},
    Router,
};
use std::sync::Arc;
use tower_http::cors::{Any, CorsLayer};

pub mod auth;
pub mod calendar;
pub mod config;
pub mod db;
pub mod handlers;
pub mod models;

use auth::AuthService;
use db::Database;

#[derive(Clone)]
pub struct AppState {
    pub auth_service: AuthService,
    pub db: Database,
}

pub async fn run_server() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize logging
    println!("🚀 Starting Calendar Backend Server");

    // Initialize database
    let database_url = std::env::var("DATABASE_URL")
        .unwrap_or_else(|_| "sqlite:calendar.db".to_string());
    
    let db = Database::new(&database_url).await?;
    println!("✅ Database initialized");

    // Create auth service
    let jwt_secret = std::env::var("JWT_SECRET")
        .unwrap_or_else(|_| "your-super-secret-jwt-key-change-in-production".to_string());

    let auth_service = AuthService::new(jwt_secret, db.clone());

    let app_state = AppState { auth_service, db };

    // Build our application with routes
    let app = Router::new()
        .route("/", get(root))
        .route("/api/health", get(health_check))
        .route("/api/auth/login", post(handlers::login))
        .route("/api/auth/verify", get(handlers::verify_token))
        .route("/api/user/info", get(handlers::get_user_info))
        .route("/api/calendar/create", post(handlers::create_calendar))
        .route("/api/calendar/delete", post(handlers::delete_calendar))
        .route("/api/calendar/events", get(handlers::get_calendar_events))
        .route("/api/calendar/events/create", post(handlers::create_event))
        .route("/api/calendar/events/update", post(handlers::update_event))
        .route("/api/calendar/events/delete", post(handlers::delete_event))
        .route("/api/calendar/events/:uid", get(handlers::refresh_event))
        // Event series-specific endpoints
        .route(
            "/api/calendar/events/series/create",
            post(handlers::create_event_series),
        )
        .route(
            "/api/calendar/events/series/update",
            post(handlers::update_event_series),
        )
        .route(
            "/api/calendar/events/series/delete",
            post(handlers::delete_event_series),
        )
        // User preferences endpoints
        .route("/api/preferences", get(handlers::get_preferences))
        .route("/api/preferences", post(handlers::update_preferences))
        .route("/api/auth/logout", post(handlers::logout))
        // External calendars endpoints
        .route("/api/external-calendars", get(handlers::get_external_calendars))
        .route("/api/external-calendars", post(handlers::create_external_calendar))
        .route("/api/external-calendars/:id", post(handlers::update_external_calendar))
        .route("/api/external-calendars/:id", delete(handlers::delete_external_calendar))
        .route("/api/external-calendars/:id/events", get(handlers::fetch_external_calendar_events))
        .layer(
            CorsLayer::new()
                .allow_origin(Any)
                .allow_methods(Any)
                .allow_headers(Any),
        )
        .with_state(Arc::new(app_state));

    // Start server
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?;
    println!("📡 Server listening on http://0.0.0.0:3000");

    axum::serve(listener, app).await?;

    Ok(())
}

async fn root() -> &'static str {
    "Calendar Backend API v0.1.0"
}

async fn health_check() -> Json<serde_json::Value> {
    Json(serde_json::json!({
        "status": "healthy",
        "service": "calendar-backend",
        "version": "0.1.0"
    }))
}
