use crate::{
    components::render_panel::messages::{MonitorInputMsg, MonitorOutputMsg},
    data::Npz,
    dynamic_col::DynamicCol,
    render::{predefined::color_mapper::BoundaryNorm, Layer, Render},
};
use glib::clone;
use std::sync::Arc;

use super::sidebar::{sidebar::SideBarModel, Msg, SideBarOutputMsg};
use adw::prelude::*;
use gtk::prelude::StyleContextExt;
use gtk::subclass::root;
use relm4::{
    component::{AsyncComponent, AsyncComponentParts},
    loading_widgets::LoadingWidgets,
    *,
};
pub struct MonitorModel {
    sidebar_open: bool,
    sidebar_width: i32,
    layers: Vec<Layer>,
    sidebar: Controller<SideBarModel>,
}

pub struct MonitorWidgets {
    paned: gtk::Paned,
}

#[relm4::component(async, pub)]
impl AsyncComponent for MonitorModel {
    type Init = ();
    type Output = MonitorOutputMsg;
    type Input = MonitorInputMsg;
    type CommandOutput = ();

    view! {
        adw::BreakpointBin {
            set_hexpand: true,
            set_vexpand: true,
            set_height_request: 500,
            set_width_request: 700,
            #[wrap(Some)]
            #[name="test"]
            set_child = &DynamicCol{
                set_end_width: 300,
                set_hexpand: true,
                set_vexpand: true,
                #[wrap(Some)]
                #[name="paned"]
                set_child_paned=&gtk::Paned{
                    #[wrap(Some)]
                    #[name="render"]
                    set_start_child=&gtk::Frame{
                        add_css_class: "rb",
                        set_margin_all: 5,
                        Render{
                            add_css_class: "rb",
                            #[watch]
                            set_interior_layers: model.layers.clone(),
                        }
                    },
                    #[wrap(Some)]
                    set_end_child=model.sidebar.widget(),
                }
            },

        }
    }

    async fn init(
        init: Self::Init,
        root: Self::Root,
        sender: relm4::AsyncComponentSender<Self>,
    ) -> AsyncComponentParts<Self> {
        let sidebar: Controller<SideBarModel> =
            SideBarModel::builder()
                .launch(())
                .forward(sender.input_sender(), |msg| match msg {
                    SideBarOutputMsg::NewLayer(layer) => MonitorInputMsg::AddLayer(layer),
                    _ => MonitorInputMsg::None,
                });
        let model = MonitorModel {
            sidebar_open: true,
            sidebar_width: 400,
            layers: vec![],
            sidebar,
        };

        let widgets = view_output! {};
        AsyncComponentParts { model, widgets }
    }

    async fn update(
        &mut self,
        msg: Self::Input,
        _sender: AsyncComponentSender<Self>,
        _root: &Self::Root,
    ) {
        tokio::time::sleep(std::time::Duration::from_millis(100)).await;
        match msg {
            MonitorInputMsg::AddLayer(layer) => {
                self.layers.push(layer);
                _sender
                    .output_sender()
                    .send(MonitorOutputMsg::LayerAdded(0))
                    .unwrap();

                self.sidebar
                    .sender()
                    .send(Msg::RefreshList(self.layers.clone()));
            }
            MonitorInputMsg::RemoveLayer(index) => {
                self.layers.remove(index);
                _sender
                    .output_sender()
                    .send(MonitorOutputMsg::LayerRemoved(0))
                    .unwrap();
            }
            MonitorInputMsg::UpdateLayer((idx, f)) => {
                f(&mut self.layers[idx]);
                _sender
                    .output_sender()
                    .send(MonitorOutputMsg::LayerUpdated(0))
                    .unwrap();
            }
            MonitorInputMsg::None => {}
        }
    }
}
