use std::sync::Arc;

use axum::{
    extract::State,
    routing::post,
    Json, Router,
};
use serde::{Deserialize, Serialize};

use crate::models::error::{ApiError, ApiResult};
use crate::AppState;

#[derive(Deserialize)]
pub struct EarlyAccessRequest {
    pub email: String,
    pub server_count: String,
}

#[derive(Serialize)]
pub struct EarlyAccessResponse {
    pub success: bool,
    pub message: String,
}

pub fn router() -> Router<Arc<AppState>> {
    Router::new().route("/", post(submit_early_access))
}

async fn submit_early_access(
    State(state): State<Arc<AppState>>,
    Json(payload): Json<EarlyAccessRequest>,
) -> ApiResult<Json<EarlyAccessResponse>> {
    // Basic validation
    let email = payload.email.trim().to_lowercase();
    if email.is_empty() || !email.contains('@') {
        return Err(ApiError::BadRequest("Invalid email address".to_string()));
    }

    let valid_counts = ["1", "2-3", "4+"];
    if !valid_counts.contains(&payload.server_count.as_str()) {
        return Err(ApiError::BadRequest("Invalid server count".to_string()));
    }

    // Check for duplicate
    let existing: Option<(i64,)> = sqlx::query_as(
        "SELECT COUNT(*) FROM early_access_signups WHERE email = $1"
    )
    .bind(&email)
    .fetch_optional(&state.db)
    .await?;

    if let Some((count,)) = existing {
        if count > 0 {
            return Ok(Json(EarlyAccessResponse {
                success: true,
                message: "You're already on the list!".to_string(),
            }));
        }
    }

    // Insert signup
    sqlx::query(
        "INSERT INTO early_access_signups (email, server_count) VALUES ($1, $2)"
    )
    .bind(&email)
    .bind(&payload.server_count)
    .execute(&state.db)
    .await?;

    tracing::info!("Early access signup: {} (servers: {})", email, payload.server_count);

    Ok(Json(EarlyAccessResponse {
        success: true,
        message: "You're on the list!".to_string(),
    }))
}
