use glib::{Variant, VariantTy, prelude::*};
use std::borrow::Cow;

use crate::gobject_models::{GArticleID, GMarked, GRead};

#[derive(Debug, Clone)]
pub struct ReadUpdate {
    pub article_id: GArticleID,
    pub read: GRead,
}

impl ToVariant for ReadUpdate {
    fn to_variant(&self) -> Variant {
        (self.article_id.clone(), self.read).to_variant()
    }
}

impl FromVariant for ReadUpdate {
    fn from_variant(variant: &Variant) -> Option<Self> {
        let article_id = variant.child_get::<GArticleID>(0);
        let read = variant.child_get::<GRead>(1);

        Some(Self { article_id, read })
    }
}

impl StaticVariantType for ReadUpdate {
    fn static_variant_type() -> Cow<'static, VariantTy> {
        Cow::Borrowed(VariantTy::new("(si)").expect("invalid variant type string"))
    }
}

#[derive(Debug, Clone)]
pub struct MarkUpdate {
    pub article_id: GArticleID,
    pub marked: GMarked,
}

impl ToVariant for MarkUpdate {
    fn to_variant(&self) -> Variant {
        (self.article_id.clone(), self.marked).to_variant()
    }
}

impl FromVariant for MarkUpdate {
    fn from_variant(variant: &Variant) -> Option<Self> {
        let article_id = variant.child_get::<GArticleID>(0);
        let marked = variant.child_get::<GMarked>(1);

        Some(Self { article_id, marked })
    }
}

impl StaticVariantType for MarkUpdate {
    fn static_variant_type() -> Cow<'static, VariantTy> {
        Cow::Borrowed(VariantTy::new("(si)").expect("invalid variant type string"))
    }
}

#[derive(Debug, Clone)]
pub struct OpenArticleInBrowser {
    pub article_id: GArticleID,
    pub url: String,
    pub read: GRead,
}

impl ToVariant for OpenArticleInBrowser {
    fn to_variant(&self) -> Variant {
        (self.article_id.clone(), self.url.clone(), self.read).to_variant()
    }
}

impl FromVariant for OpenArticleInBrowser {
    fn from_variant(variant: &Variant) -> Option<Self> {
        let article_id = variant.child_get::<GArticleID>(0);
        let url = variant.child_get::<String>(1);
        let read = variant.child_get::<GRead>(2);

        Some(Self { article_id, url, read })
    }
}

impl StaticVariantType for OpenArticleInBrowser {
    fn static_variant_type() -> Cow<'static, VariantTy> {
        Cow::Borrowed(VariantTy::new("(ssi)").expect("invalid variant type string"))
    }
}
