pub mod auth;
pub mod group;
pub mod pool;
pub mod token;
pub mod user;

use crate::errors::CognitoError;
use crate::server::AppState;
use axum::response::Response;
use std::sync::Arc;

/// Convert an RFC 3339 timestamp string to epoch seconds (f64).
///
/// The AWS SDK expects date fields like `CreationDate` and
/// `LastModifiedDate` to be numeric epoch seconds, not ISO 8601
/// strings.  This helper parses the stored RFC 3339 value and
/// returns the corresponding Unix timestamp as a float.
pub(crate) fn epoch_secs(rfc3339: &str) -> f64 {
    chrono::DateTime::parse_from_rfc3339(rfc3339)
        .map(|dt| dt.timestamp() as f64)
        .unwrap_or(0.0)
}

pub async fn dispatch(
    operation: &str,
    body: serde_json::Value,
    state: &Arc<AppState>,
) -> Result<Response, CognitoError> {
    match operation {
        "CreateUserPool" => pool::create_user_pool(body, state).await,
        "DescribeUserPool" => pool::describe_user_pool(body, state).await,
        "ListUserPools" => pool::list_user_pools(body, state).await,
        "DeleteUserPool" => pool::delete_user_pool(body, state).await,
        "CreateUserPoolClient" => pool::create_user_pool_client(body, state).await,
        "DescribeUserPoolClient" => pool::describe_user_pool_client(body, state).await,
        "ListUserPoolClients" => pool::list_user_pool_clients(body, state).await,
        "CreateUserPoolDomain" => pool::create_user_pool_domain(body, state).await,

        "AdminCreateUser" => user::admin_create_user(body, state).await,
        "AdminDeleteUser" => user::admin_delete_user(body, state).await,
        "AdminGetUser" => user::admin_get_user(body, state).await,
        "ListUsers" => user::list_users(body, state).await,
        "AdminSetUserPassword" => user::admin_set_user_password(body, state).await,
        "AdminUpdateUserAttributes" => user::admin_update_user_attributes(body, state).await,

        "SignUp" => auth::sign_up(body, state).await,
        "ConfirmSignUp" => auth::confirm_sign_up(body, state).await,
        "InitiateAuth" => auth::initiate_auth(body, state).await,
        "AdminInitiateAuth" => auth::admin_initiate_auth(body, state).await,
        "RespondToAuthChallenge" => auth::respond_to_auth_challenge(body, state).await,

        "GetUser" => token::get_user(body, state).await,
        "GlobalSignOut" => token::global_sign_out(body, state).await,
        "AdminUserGlobalSignOut" => token::admin_user_global_sign_out(body, state).await,

        "CreateGroup" => group::create_group(body, state).await,
        "AdminAddUserToGroup" => group::admin_add_user_to_group(body, state).await,
        "AdminListGroupsForUser" => group::admin_list_groups_for_user(body, state).await,
        "ListGroups" => group::list_groups(body, state).await,

        _ => Err(CognitoError::InvalidParameter(format!(
            "Unknown operation: {operation}"
        ))),
    }
}
