use self::SignatureCollapse::*;
use super::*;

pub trait SignatureContainer {
    fn get_signature(&self) -> Html;
    fn get_id(&self) -> String;
    fn get_class(&self) -> String;
    fn get_children(&self) -> Option<Html> {
        None
    }
    fn get_source(&self) -> String {
        String::new()
    }
    fn get_link(&self) -> String {
        String::new()
    }
}

#[derive(Clone, Debug, Properties)]
pub struct SignatureData<T: Clone + SignatureContainer> {
    pub data: T,
}

#[derive(Clone, Debug)]
pub struct SignatureComponent<T>
where
    T: 'static + Clone + SignatureContainer,
{
    data: T,
    link: ComponentLink<Self>,
    collapse: Option<bool>,
    children: Option<Html>,
}

#[derive(Copy, Clone, Debug)]
pub enum SignatureCollapse {
    CollapseClick,
}

impl<T> Component for SignatureComponent<T>
where
    T: 'static + SignatureContainer + Clone,
{
    type Message = SignatureCollapse;
    type Properties = SignatureData<T>;

    fn create(data: Self::Properties, link: ComponentLink<Self>) -> Self {
        let children = data.data.get_children();
        let collapse = match children {
            Some(_) => Some(true),
            None => None,
        };
        Self { data: data.data, link, collapse, children }
    }

    fn update(&mut self, _: Self::Message) -> ShouldRender {
        if let Some(state) = self.collapse {
            self.collapse = Some(!state);
        }
        true
    }

    fn change(&mut self, _: Self::Properties) -> ShouldRender {
        false
    }

    fn view(&self) -> Html {
        let id = self.data.get_id();
        let class = self.data.get_class();
        let subclass = format!("{}-items", class);
        let src = SourceLink(self.data.get_source());
        let code = self.data.get_signature();
        let a = Anchor(format!("#{}", id));
        let collapse = match self.collapse {
            None => html! {
            //  <span class="collapse-toggle" title="Document Missing">{"[x]"}</span>
                <span class="collapse-toggle">{"[x]"}</span>
            },
            Some(true) => html! {
                <span class="collapse-toggle clickable" onclick=self.link.callback(|_| CollapseClick)>{"[-]"}</span>
            },
            Some(false) => html! {
                <span class="collapse-toggle clickable" onclick=self.link.callback(|_| CollapseClick)>{"[+]"}</span>
            },
        };
        let style = match self.collapse {
            None => "display: flex;",
            Some(true) => "display: flex;",
            Some(false) => "display: none;",
        };
        match self.children.clone() {
            Some(inner) => html! {
            <>
                <div id=id class=class style="display: flex;">{code}{a}{src}{collapse}</div>
                <div class=subclass style=style>{inner}</div>
            </>
            },
            None => html! {
                <div id=id class=class style="display: flex;">{code}{a}{src}{collapse}</div>
            },
        }
    }
}