use crate::app_config::AppConfig;
use crate::server::custom_error::HttpResult;
use actix_identity::Identity;
use actix_remote_ip::RemoteIP;
use actix_web::{HttpMessage, HttpRequest, HttpResponse, web};

#[derive(serde::Deserialize)]
pub struct AuthRequest {
    user: String,
    password: String,
}

/// Perform password authentication
pub async fn password_auth(
    r: web::Json<AuthRequest>,
    request: HttpRequest,
    remote_ip: RemoteIP,
) -> HttpResult {
    if r.user != AppConfig::get().admin_username || r.password != AppConfig::get().admin_password {
        log::error!("Failed login attempt from {}!", remote_ip.0);
        return Ok(HttpResponse::Unauthorized().json("Invalid credentials!"));
    }

    log::info!("Successful login attempt from {}!", remote_ip.0);
    Identity::login(&request.extensions(), r.user.to_string())?;
    Ok(HttpResponse::Ok().finish())
}

#[derive(serde::Serialize)]
struct AuthInfo {
    id: String,
}

/// Get current user information
pub async fn auth_info(id: Option<Identity>) -> HttpResult {
    if AppConfig::get().unsecure_disable_login {
        return Ok(HttpResponse::Ok().json(AuthInfo {
            id: "auto login".to_string(),
        }));
    }

    Ok(HttpResponse::Ok().json(AuthInfo {
        id: id.unwrap().id()?,
    }))
}

/// Sign out user
pub async fn sign_out(id: Identity) -> HttpResult {
    id.logout();

    Ok(HttpResponse::NoContent().finish())
}