//! The type that represents a composition object.
//!
//! <https://api.slack.com/reference/surfaces/formatting#rich-layouts>

use crate::Block;
use serde::Serialize;

/// The type that represents a composition object.
///
/// <https://api.slack.com/reference/surfaces/formatting#rich-layouts>
#[derive(Serialize, Debug, Clone)]
#[serde(untagged)]
pub enum Layouts {
    /// Defining a single block.
    ///
    /// <https://api.slack.com/reference/surfaces/formatting#define_block>
    SingleBlock(Box<Block>),

    /// Stacking multiple blocks.
    ///
    /// <https://api.slack.com/reference/surfaces/formatting#stack_of_blocks>
    MultipleBlocks(Vec<Block>),

    /// Adding your blocks array.
    ///
    /// <https://api.slack.com/reference/surfaces/formatting#add_blocks_array>
    BlocksArray(MessagePayloads),
}

/// Message payloads.
///
/// <https://api.slack.com/surfaces/messages#payloads>
#[derive(Serialize, Debug, Clone)]
#[serde(rename_all = "snake_case")]
pub struct MessagePayloads {
    /// The usage of this field changes depending on whether you're using `blocks` or not.
    pub text: String,

    /// An array of [layout blocks](https://api.slack.com/reference/block-kit/blocks) in the same format [as described in the building blocks guide](https://api.slack.com/block-kit/building).
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub blocks: Vec<Block>,

    /// An array of [legacy secondary attachments](https://api.slack.com/reference/messaging/attachments).
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub attachments: Vec<String>,

    /// The [ID of another un-threaded message](https://api.slack.com/surfaces/messages#threading) to reply to.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub thread_ts: Option<String>,

    /// Determines whether the text field is rendered according to [`mrkdwn` formatting or not](https://api.slack.com/reference/surfaces/formatting#basics).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub mrkdwn: Option<bool>,
}
