// @generated by flare-im-core-sdk-xtask
// Source: bindings/contract/dispatch.json

// Do not edit by hand.
#![allow(clippy::too_many_lines, unused_imports)]

use crate::dispatch_support::*;
use crate::{BindingResponse, binding_operation_not_supported};
use flare_im_core_sdk::Result;
use flare_im_core_sdk::client::api::MessageApi;
use flare_im_core_sdk::model::MessageSearchQuery;
use flare_im_core_sdk::serde_json::{self, Value};

pub const MESSAGE_DISPATCH_OPERATIONS: &[&str] = &[
    "get",
    "get_raw",
    "search",
    "search_by_query",
    "search_in_conversation",
    "list",
    "send",
    "send_no_oss",
    "recall",
    "delete",
    "delete_for_self",
    "delete_for_everyone",
    "edit_text_by_message_id",
    "edit_rich_doc_by_message_id",
    "mark_read_and_burn",
    "typing",
    "add_reaction",
    "remove_reaction",
    "pin",
    "unpin",
    "pin_by_message_id",
    "unpin_by_message_id",
    "mark",
    "mark_with_color",
    "unmark",
    "mark_by_message_id",
    "unmark_by_message_id",
];

pub fn is_message_operation(operation: &str) -> bool {
    MESSAGE_DISPATCH_OPERATIONS.contains(&operation)
}

pub async fn dispatch_message(
    api: &MessageApi,
    operation: &str,
    params: Value,
) -> Result<BindingResponse> {
    match operation {
        "get" => {
            let message_id_s = json_string(&params, "messageId")?;
            json(api.get(&message_id_s).await?)
        }
        "get_raw" => {
            let message_id_s = json_string(&params, "messageId")?;
            json(api.get_raw(&message_id_s).await?)
        }
        "search" => {
            let keyword_s = json_string(&params, "keyword")?;
            let limit_v = optional_i32(&params, "limit")?.unwrap_or(50).max(1) as u32;
            let messages = api.search(&keyword_s, limit_v).await?;
            json(serde_json::json!({ "messages": messages }))
        }
        "search_by_query" => {
            let bound_value: MessageSearchQuery = from_value(params.clone(), "MessageSearchQuery")?;
            let messages = api.search_by_query(bound_value).await?;
            json(serde_json::json!({ "messages": messages }))
        }
        "search_in_conversation" => {
            let conversation_id_s = json_string(&params, "conversationId")?;
            let keyword_s = json_string(&params, "keyword")?;
            let limit_v = optional_i32(&params, "limit")?.unwrap_or(50).max(1) as u32;
            let messages = api
                .search_in_conversation(&conversation_id_s, &keyword_s, limit_v)
                .await?;
            json(serde_json::json!({ "messages": messages }))
        }
        "list" => {
            let conversation_id_s = json_string(&params, "conversationId")?;
            let before_seq_v = json_u64(&params, "beforeSeq")?;
            let limit_v = optional_i32(&params, "limit")?.unwrap_or(50).max(1) as u32;
            let messages = api.list(&conversation_id_s, before_seq_v, limit_v).await?;
            json(serde_json::json!({ "messages": messages }))
        }
        "send" => json_send_ack(api.send(message_from_params(&params)?).await?),
        "send_no_oss" => json_send_ack(api.send_no_oss(message_from_params(&params)?).await?),
        "recall" => {
            let message_id_s = json_string(&params, "messageId")?;
            api.recall(&message_id_s).await?;
            Ok(BindingResponse::unit())
        }
        "delete" => {
            let message_id_s = json_string(&params, "messageId")?;
            api.delete(&message_id_s).await?;
            Ok(BindingResponse::unit())
        }
        "delete_for_self" => {
            let message_id_s = json_string(&params, "messageId")?;
            let reason_o = optional_string(&params, "reason");
            api.delete_for_self(&message_id_s, reason_o).await?;
            Ok(BindingResponse::unit())
        }
        "delete_for_everyone" => {
            let message_id_s = json_string(&params, "messageId")?;
            let reason_o = optional_string(&params, "reason");
            api.delete_for_everyone(&message_id_s, reason_o).await?;
            Ok(BindingResponse::unit())
        }
        "edit_text_by_message_id" => {
            let message_id_s = json_string(&params, "messageId")?;
            let text_s = json_string(&params, "text")?;
            api.edit_text_by_message_id(&message_id_s, &text_s).await?;
            Ok(BindingResponse::unit())
        }
        "edit_rich_doc_by_message_id" => {
            api.edit_rich_doc_by_message_id(
                from_value::<EditRichDocJson>(params.clone(), "rich doc edit")?.into(),
            )
            .await?;
            Ok(BindingResponse::unit())
        }
        "mark_read_and_burn" => {
            let message_id_s = json_string(&params, "messageId")?;
            api.mark_read_and_burn(&message_id_s).await?;
            Ok(BindingResponse::unit())
        }
        "typing" => {
            let conversation_id_s = json_string(&params, "conversationId")?;
            let typing_v = json_bool(&params, "typing")?;
            api.typing(&conversation_id_s, typing_v).await?;
            Ok(BindingResponse::unit())
        }
        "add_reaction" => {
            let message_id_s = json_string(&params, "messageId")?;
            let emoji_s = json_string(&params, "emoji")?;
            api.add_reaction(&message_id_s, &emoji_s).await?;
            Ok(BindingResponse::unit())
        }
        "remove_reaction" => {
            let message_id_s = json_string(&params, "messageId")?;
            let emoji_s = json_string(&params, "emoji")?;
            api.remove_reaction(&message_id_s, &emoji_s).await?;
            Ok(BindingResponse::unit())
        }
        "pin" => {
            let conversation_id_s = json_string(&params, "conversationId")?;
            let message_id_s = json_string(&params, "messageId")?;
            let scope_v = json_i32(&params, "scope")?;
            api.pin(&conversation_id_s, &message_id_s, scope_v).await?;
            Ok(BindingResponse::unit())
        }
        "unpin" => {
            let conversation_id_s = json_string(&params, "conversationId")?;
            let message_id_s = json_string(&params, "messageId")?;
            let scope_v = json_i32(&params, "scope")?;
            api.unpin(&conversation_id_s, &message_id_s, scope_v)
                .await?;
            Ok(BindingResponse::unit())
        }
        "pin_by_message_id" => {
            let message_id_s = json_string(&params, "messageId")?;
            let scope_v = json_i32(&params, "scope")?;
            api.pin_by_message_id(&message_id_s, scope_v).await?;
            Ok(BindingResponse::unit())
        }
        "unpin_by_message_id" => {
            let message_id_s = json_string(&params, "messageId")?;
            let scope_v = json_i32(&params, "scope")?;
            api.unpin_by_message_id(&message_id_s, scope_v).await?;
            Ok(BindingResponse::unit())
        }
        "mark" => {
            let conversation_id_s = json_string(&params, "conversationId")?;
            let message_id_s = json_string(&params, "messageId")?;
            let mark_type_v = parse_mark_type(json_i32(&params, "markType")?);
            api.mark(&conversation_id_s, &message_id_s, mark_type_v)
                .await?;
            Ok(BindingResponse::unit())
        }
        "mark_with_color" => {
            let conversation_id_s = json_string(&params, "conversationId")?;
            let message_id_s = json_string(&params, "messageId")?;
            let mark_type_v = parse_mark_type(json_i32(&params, "markType")?);
            let color_s = json_string(&params, "color")?;
            api.mark_with_color(&conversation_id_s, &message_id_s, mark_type_v, &color_s)
                .await?;
            Ok(BindingResponse::unit())
        }
        "unmark" => {
            let conversation_id_s = json_string(&params, "conversationId")?;
            let message_id_s = json_string(&params, "messageId")?;
            let mark_type_v = parse_mark_type(json_i32(&params, "markType")?);
            api.unmark(&conversation_id_s, &message_id_s, mark_type_v)
                .await?;
            Ok(BindingResponse::unit())
        }
        "mark_by_message_id" => {
            let message_id_s = json_string(&params, "messageId")?;
            let mark_type_v = parse_mark_type(json_i32(&params, "markType")?);
            let color_s = json_string(&params, "color")?;
            api.mark_by_message_id(&message_id_s, mark_type_v, &color_s)
                .await?;
            Ok(BindingResponse::unit())
        }
        "unmark_by_message_id" => {
            let message_id_s = json_string(&params, "messageId")?;
            let mark_type_v = parse_mark_type(json_i32(&params, "markType")?);
            api.unmark_by_message_id(&message_id_s, mark_type_v).await?;
            Ok(BindingResponse::unit())
        }
        _ => Err(binding_operation_not_supported(operation)),
    }
}

pub async fn dispatch_message_json(
    api: &MessageApi,
    operation: &str,
    params_json: &str,
) -> Result<BindingResponse> {
    match operation {
        "search_by_query" => {
            let bound_value: MessageSearchQuery = from_json_str(params_json, "MessageSearchQuery")?;
            let messages = api.search_by_query(bound_value).await?;
            json(serde_json::json!({ "messages": messages }))
        }
        "send" => json_send_ack(api.send(message_from_json_str(params_json)?).await?),
        "send_no_oss" => json_send_ack(api.send_no_oss(message_from_json_str(params_json)?).await?),
        "edit_rich_doc_by_message_id" => {
            api.edit_rich_doc_by_message_id(
                from_json_str::<EditRichDocJson>(params_json, "rich doc edit")?.into(),
            )
            .await?;
            Ok(BindingResponse::unit())
        }
        _ => {
            let params = dispatch_params_from_json(params_json)?;
            dispatch_message(api, operation, params).await
        }
    }
}
