use news_flash::models::{ArticleID, CategoryID, FeedID, TagID};
use serde::{Deserialize, Serialize};
use std::fmt;

#[derive(Hash, Eq, Clone, Debug, Serialize, Deserialize)]
pub enum UndoAction {
    MarkRead(Vec<ArticleID>),
    DeleteFeed(FeedID, String),
    DeleteCategory(CategoryID, String),
    DeleteTag(TagID, String),
}

impl fmt::Display for UndoAction {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            UndoAction::MarkRead(ids) => write!(f, "Mark Read {} articles", ids.len()),
            UndoAction::DeleteFeed(id, label) => write!(f, "Delete Feed '{label}' (id: {id})"),
            UndoAction::DeleteCategory(id, label) => write!(f, "Delete Category '{label}' (id: {id})"),
            UndoAction::DeleteTag(id, label) => write!(f, "Delete Tag '{label}' (id: {id})"),
        }
    }
}

impl PartialEq for UndoAction {
    fn eq(&self, other: &Self) -> bool {
        match self {
            UndoAction::MarkRead(self_ids) => match other {
                UndoAction::MarkRead(other_ids) => self_ids == other_ids,
                _ => false,
            },
            UndoAction::DeleteFeed(self_id, _self_title) => match other {
                UndoAction::DeleteFeed(other_id, __other_title) => self_id == other_id,
                _ => false,
            },
            UndoAction::DeleteCategory(self_id, _title) => match other {
                UndoAction::DeleteCategory(other_id, __other_title) => self_id == other_id,
                _ => false,
            },
            UndoAction::DeleteTag(self_id, _title) => match other {
                UndoAction::DeleteTag(other_id, __other_title) => self_id == other_id,
                _ => false,
            },
        }
    }
}
