use rocket::form::Form;
use rocket_i18n::I18n;

use crate::counters;
use crate::tokens::{self, StatelessSerializable};
use crate::web::{MyResponse, RequestOrigin};
use hagrid_database::{Database, Sqlite, types::Email, types::Fingerprint};
use serde_derive::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub struct StatelessVerifyToken {
    pub fpr: Fingerprint,
}
impl StatelessSerializable for StatelessVerifyToken {}

pub mod templates {
    use serde_derive::Serialize;

    #[derive(Serialize)]
    pub struct ManageKey {
        pub key_fpr: String,
        pub key_link: String,
        pub base_uri: String,
        pub uid_status: Vec<ManageKeyUidStatus>,
        pub token: String,
    }

    #[derive(Serialize)]
    pub struct ManageLinkSent {
        pub address: String,
    }

    #[derive(Serialize)]
    pub struct ManageKeyUidStatus {
        pub address: String,
        pub published: bool,
    }
}

pub mod forms {
    use rocket::FromForm;

    #[derive(FromForm)]
    pub struct ManageRequest {
        pub search_term: String,
    }

    #[derive(FromForm)]
    pub struct ManageDelete {
        pub token: String,
        pub address: String,
    }
}

pub fn vks_manage_unpublish_or_fail(
    origin: RequestOrigin,
    db: &rocket::State<Sqlite>,
    token_service: &rocket::State<tokens::Service>,
    i18n: I18n,
    request: Form<forms::ManageDelete>,
) -> anyhow::Result<MyResponse> {
    let verify_token = token_service.check::<StatelessVerifyToken>(&request.token)?;
    let email = request.address.parse::<Email>()?;

    db.set_email_unpublished(&verify_token.fpr, &email)?;
    counters::inc_address_unpublished(&email);

    Ok(crate::routes::manage::vks_manage_key(
        origin,
        db,
        i18n,
        request.token.to_owned(),
        token_service,
    ))
}
