use serde::{Deserialize, Serialize};
use std::collections::HashSet;
use ts_rs::TS;

use crate::types::Id;
use crate::{Packed, Required};
use magnetar_sdk_macros::pack;

#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
pub struct EmojiBase {
    pub shortcode: String,
    pub url: String,
    pub category: Option<String>,
    pub width: Option<i32>,
    pub height: Option<i32>,
}

pack!(PackEmojiBase, Required<Id> as id & Required<EmojiBase> as emoji);

#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
#[repr(transparent)]
pub struct EmojiContext(pub Vec<PackEmojiBase>);

impl EmojiContext {
    pub fn extend_from(&mut self, more: &[PackEmojiBase]) {
        let existing = self
            .0
            .iter()
            .map(|e| e.emoji.0.shortcode.clone())
            .collect::<HashSet<_>>();

        self.0.extend(
            more.iter()
                .filter(|&e| !existing.contains(&e.emoji.0.shortcode))
                .cloned(),
        );
    }
}
