use crate::app::App;
use crate::gobject_models::GEnclosure;
use glib::{Object, Properties, subclass::prelude::*, subclass::*};
use gtk4::{Accessible, Buildable, CompositeTemplate, ConstraintTarget, Widget, prelude::*, subclass::prelude::*};
use libadwaita::{Bin, subclass::prelude::*};
use std::cell::RefCell;

mod imp {
    use super::*;

    #[derive(Debug, Default, CompositeTemplate, Properties)]
    #[properties(wrapper_type = super::LinkPreview)]
    #[template(file = "data/resources/ui_templates/article_view/enclosure_link.blp")]
    pub struct LinkPreview {
        #[property(get, set, nullable, construct_only)]
        pub title: RefCell<Option<String>>,

        #[property(get, set, construct_only)]
        pub url: RefCell<String>,

        #[property(get, set, nullable, construct_only)]
        pub author: RefCell<Option<String>>,

        #[property(get, set, nullable, construct_only)]
        pub mime: RefCell<Option<String>>,
    }

    #[glib::object_subclass]
    impl ObjectSubclass for LinkPreview {
        const NAME: &'static str = "LinkPreview";
        type Type = super::LinkPreview;
        type ParentType = Bin;

        fn class_init(klass: &mut Self::Class) {
            klass.bind_template();
            klass.bind_template_callbacks();
            klass.set_css_name("link_preview");
        }

        fn instance_init(obj: &InitializingObject<Self>) {
            obj.init_template();
        }
    }

    #[glib::derived_properties]
    impl ObjectImpl for LinkPreview {}

    impl WidgetImpl for LinkPreview {}

    impl BinImpl for LinkPreview {}

    #[gtk4::template_callbacks]
    impl LinkPreview {
        #[template_callback]
        fn on_click(&self) {
            App::open_url_in_default_browser(self.url.borrow().as_str());
        }

        #[template_callback]
        fn icon_name(&self, mime: Option<&str>) -> &'static str {
            let Some(mime) = mime else {
                return "globe-alt-symbolic";
            };

            if mime.starts_with("video") || mime == "application/x-shockwave-flash" {
                "video-x-generic-symbolic"
            } else if mime.starts_with("image") {
                "image-x-generic-symbolic"
            } else if mime.starts_with("audio") {
                "audio-x-generic-symbolic"
            } else {
                "globe-alt-symbolic"
            }
        }

        #[template_callback]
        fn is_some(&self, text: Option<&str>) -> bool {
            text.is_some()
        }

        #[template_callback]
        fn line_num(&self, text: Option<&str>) -> i32 {
            if text.is_some() { 1 } else { 3 }
        }
    }
}

glib::wrapper! {
    pub struct LinkPreview(ObjectSubclass<imp::LinkPreview>)
        @extends Widget, Bin,
        @implements Accessible, Buildable, ConstraintTarget;
}

impl From<&GEnclosure> for LinkPreview {
    fn from(value: &GEnclosure) -> Self {
        Object::builder()
            .property("url", value.url())
            .property("title", value.title())
            .property("author", value.author())
            .property("mime", value.mime_type())
            .build()
    }
}
