use serde::Deserialize;
use serde::Serialize;

use super::ast_node::WasmAstNode;
use super::macros::to_wasm;
use super::to_wasm::ToWasm;
use crate::compare::ElispFact;
use crate::types::CheckboxType;
use crate::types::PlainListItem;
use crate::types::PlainListItemCounter;
use crate::types::PlainListItemPreBlank;
use crate::wasm::to_wasm::ToWasmStandardProperties;

#[derive(Debug, Serialize, Deserialize)]
pub struct WasmPlainListItem {
    pub(crate) tag: Vec<WasmAstNode>,
    pub(crate) bullet: String,
    pub(crate) counter: Option<PlainListItemCounter>,
    pub(crate) checkbox: Option<String>,
    #[serde(rename = "pre-blank")]
    pub(crate) pre_blank: PlainListItemPreBlank,
}

to_wasm!(
    WasmPlainListItem,
    PlainListItem<'s>,
    original,
    wasm_context,
    { WasmAstNode::PlainListItem(original) },
    { "item".into() },
    {
        let children = original
            .children
            .iter()
            .map(|child| {
                child
                    .to_wasm(wasm_context.clone())
                    .map(Into::<WasmAstNode>::into)
            })
            .collect::<Result<Vec<_>, _>>()?;

        Ok((
            children,
            WasmPlainListItem {
                tag: Vec::new(),
                bullet: original.bullet.to_owned(),
                counter: original.counter.clone(),
                checkbox: original.checkbox.as_ref().map(|(checkbox_type, _)| {
                    match checkbox_type {
                        CheckboxType::On => "on",
                        CheckboxType::Trans => "trans",
                        CheckboxType::Off => "off",
                    }
                    .to_owned()
                }),
                pre_blank: original.pre_blank,
            },
        ))
    }
);