use axum::{debug_handler, extract::Path, response::Response};
// [`axum_extra`]'s form extractor is preferred:
// https://docs.rs/axum-extra/0.10.1/axum_extra/extract/struct.Form.html#differences-from-axumextractform
use axum_extra::extract::Form;
use phono_backends::pg_acl::PgPrivilegeType;
use phono_models::rel_invitation::RelInvitation;
use serde::Deserialize;
use sqlx::postgres::types::Oid;
use uuid::Uuid;

use crate::{
    app::AppDbConn,
    errors::AppError,
    navigator::{Navigator, NavigatorPage as _},
    user::CurrentUser,
};

#[derive(Debug, Deserialize)]
pub(super) struct PathParams {
    rel_oid: u32,
    workspace_id: Uuid,
}

#[derive(Debug, Deserialize)]
pub(super) struct FormBody {
    email: String,
}

/// HTTP POST handler for inviting another Phonograph user to collaborate on a
/// relation, by email address.
#[debug_handler(state = crate::app::App)]
pub(super) async fn post(
    AppDbConn(mut app_db): AppDbConn,
    CurrentUser(user): CurrentUser,
    navigator: Navigator,
    Path(PathParams {
        rel_oid,
        workspace_id,
    }): Path<PathParams>,
    Form(form): Form<FormBody>,
) -> Result<Response, AppError> {
    // FIXME: Check workspace authorization.
    // FIXME ensure workspace corresponds to rel/portal, and that user has
    // permission to access/alter both as needed.
    // FIXME form validation
    for privilege in [
        PgPrivilegeType::Select,
        PgPrivilegeType::Insert,
        PgPrivilegeType::Update,
        PgPrivilegeType::Delete,
        PgPrivilegeType::Truncate,
        PgPrivilegeType::References,
        PgPrivilegeType::Trigger,
    ] {
        RelInvitation::upsertable()
            .email(form.email.clone())
            .workspace_id(workspace_id)
            .class_oid(Oid(rel_oid))
            .privilege(privilege)
            .created_by(user.id)
            .build()?
            .upsert(&mut app_db)
            .await?;
    }
    Ok(navigator
        .rel_page()
        .workspace_id(workspace_id)
        .rel_oid(Oid(rel_oid))
        .suffix("settings/")
        .build()?
        .redirect_to())
}
