use crate::ui::db_browser::DbBrowserMsg;
use crate::ui::home_page::HomePage;
use crate::ui::home_page::HomePageMsg;
use crate::ui::jlc_downloader::JlcDownloaderMsg;
use crate::ui::part_viewer::PartViewerMsg;
use iced::Subscription;
use iced::Task;
use iced::color;
use tracing::info;
use tracing::warn;
use crate::widgets::toast;

#[allow(unused_imports)]
use super::db_browser;
#[allow(unused_imports)]
use super::home_page;
#[allow(unused_imports)]
use super::jlc_downloader;
#[allow(unused_imports)]
use super::part_viewer;
use iced::Theme;
#[allow(unused_imports)]
use iced::widget as w;
use iced::widget::button;
use iced::widget::row;
#[allow(unused_imports)]
use iced::{
    Element, Length,
    alignment::{Horizontal, Vertical},
    widget::{Column, Container, Text, column},
};
use std::fmt::Display;

#[allow(dead_code)]
struct MainWindow {
    title: String,
    theme: iced::Theme,
    curr_tab: TabId,
    home_page: crate::ui::home_page::HomePage,
    jlc_downloader: crate::ui::jlc_downloader::JlcDownloader,
    db_browser: crate::ui::db_browser::DbBrowser,
    part_viewer: crate::ui::part_viewer::PartViewer,
    explain: bool,
    toasts:Vec<toast::Toast>,
}
impl Default for MainWindow {
    fn default() -> Self {
        let mut home_page = HomePage::default();
        let mut theme = Theme::default();
        if let Ok(saved_theme) = crate::utils::app_settings::get_curr_theme() {
            theme = Theme::ALL[saved_theme as usize % Theme::ALL.len()].clone();
            home_page.theme = theme.clone();
        }
        let mut jlc_downloader = crate::ui::jlc_downloader::JlcDownloader::default();
        jlc_downloader.set_theme(theme.clone());
        jlc_downloader.step_save_dir = home_page.step_dir.clone();
        Self {
            title: "HardwareToolkit".into(),
            theme,
            curr_tab: Default::default(),
            home_page,
            jlc_downloader,
            db_browser: Default::default(),
            part_viewer: Default::default(),
            explain: false,
            toasts:Default::default(),
        }
    }
}
impl MainWindow {
    pub fn new() -> (Self, Task<MainWindowMsg>) {
        (Self::default(), Task::batch([iced::widget::focus_next()]))
    }
}

pub fn main_window() {
    let _ = iced::application(MainWindow::new, MainWindow::update, MainWindow::view)
        .theme(MainWindow::theme)
        .default_font(iced::Font::with_name("微软雅黑"))
        .title(MainWindow::title)
        .subscription(MainWindow::subscription)
        .run();
}

#[allow(dead_code)]
#[derive(Debug, Clone)]
pub enum MainWindowMsg {
    ThemeChanged(iced::Theme),
    SearchKeywordChanged(String),
    TitleChanged(String),
    TabSelected(TabId),
    HomePage(HomePageMsg),
    JlcDownloader(JlcDownloaderMsg),
    DbBrowser(DbBrowserMsg),
    PartViewer(PartViewerMsg),
    Explain(bool),
    Toast(toast::Toast),
    CloseToast(usize),
    Nothing,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum TabId {
    HomePage,
    JlcDownloader,
    DbBrowser,
    PartViewer,
}
impl Default for TabId {
    fn default() -> Self {
        if let Ok(tab) = crate::utils::app_settings::get_curr_page() {
            Self::from(tab)
        } else {
            Self::HomePage
        }
    }
}
impl TabId {
    pub fn save(&self) {
        let v = *self;
        match crate::utils::app_settings::set_curr_page(v.into()) {
            Ok(_) => {}
            Err(_) => {
                warn!("Failed to save the current page.");
            }
        }
    }
}
impl Display for TabId {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "{}",
            match self {
                TabId::HomePage => "主页",
                TabId::JlcDownloader => "3D模型下载",
                TabId::DbBrowser => "数据库浏览",
                TabId::PartViewer => "元件查看",
            }
        )
    }
}
impl From<TabId> for u32 {
    fn from(val: TabId) -> Self {
        match val {
            TabId::HomePage => 0,
            TabId::JlcDownloader => 1,
            TabId::DbBrowser => 2,
            TabId::PartViewer => 3,
        }
    }
}
impl From<u32> for TabId {
    fn from(value: u32) -> Self {
        match value {
            0 => Self::HomePage,
            1 => Self::JlcDownloader,
            2 => Self::DbBrowser,
            3 => Self::PartViewer,
            _ => Self::HomePage,
        }
    }
}
impl MainWindow {
    fn title(&self) -> String {
        self.title.clone()
    }
    fn theme(&self) -> Theme {
        self.theme.clone()
    }

    fn subscription(&self) -> Subscription<MainWindowMsg> {
        info!("subscription run once.");
        iced::keyboard::on_key_press(|key, modifiers| {
            info!("Press the key: {key:?}");
            info!("The modifiers: {modifiers:?}");
            Some(MainWindowMsg::Nothing)
        })
    }
    fn create_tab_btn(&self, tab: TabId) -> Element<'_, MainWindowMsg> {
        let btn_style = if self.curr_tab == tab {
            button::danger
        } else {
            button::primary
        };
        let txt = format!("{tab}");
        let txt = iced::widget::text(txt);
        let btn = button(txt).style(btn_style);
        btn.on_press(MainWindowMsg::TabSelected(tab)).into()
    }
    fn update(&mut self, msg: MainWindowMsg) -> Task<MainWindowMsg> {
        match msg {
            MainWindowMsg::ThemeChanged(theme) => {
                self.theme = theme.clone();
                if let Some(idx) = Theme::ALL.iter().position(|x| x == &theme) {
                    crate::utils::app_settings::set_curr_theme(idx as u32).unwrap();
                }
                self.home_page.set_theme(theme);
                self.home_page.update(HomePageMsg::Nothing)
            }
            MainWindowMsg::TitleChanged(title) => {
                self.title = title;
                Task::none()
            }
            MainWindowMsg::Nothing => {
                info!("Nothing");
                iced::debug::time("Test".to_owned());
                Task::none()
            }
            MainWindowMsg::TabSelected(i) => {
                self.curr_tab = i;
                self.curr_tab.save();
                Task::none()
            }
            MainWindowMsg::HomePage(msg) => {
                info!("update HomePage");
                self.home_page.update(msg)
            }
            MainWindowMsg::JlcDownloader(msg) => self.jlc_downloader.update(msg),
            MainWindowMsg::DbBrowser(msg) => self.db_browser.update(msg),
            MainWindowMsg::PartViewer(part_viewer_msg) => self.part_viewer.update(part_viewer_msg),
            MainWindowMsg::SearchKeywordChanged(k) => self
                .jlc_downloader
                .update(JlcDownloaderMsg::KeywordChanged(k)),
            MainWindowMsg::Explain(explain) => {
                self.explain = explain;
                Task::none()
            }
            MainWindowMsg::Toast(t)=>{
                self.toasts.push(t.clone());
                Task::none()
            }
            MainWindowMsg::CloseToast(i)=>{
                self.toasts.remove(i);
                Task::none()
            }
        }
    }
    fn view(&self) -> Element<'_, MainWindowMsg> {
        let h = row![
            self.create_tab_btn(TabId::HomePage),
            self.create_tab_btn(TabId::JlcDownloader),
            self.create_tab_btn(TabId::DbBrowser),
            self.create_tab_btn(TabId::PartViewer),
            iced::widget::horizontal_space().width(Length::Fill),
            iced::widget::checkbox("Explain", self.explain).on_toggle(MainWindowMsg::Explain),
        ];
        let v = match self.curr_tab {
            TabId::HomePage => {
                if self.explain {
                    self.home_page.view().explain(color!(0xff0000))
                } else {
                    self.home_page.view()
                }
            }
            TabId::JlcDownloader => {
                if self.explain {
                    self.jlc_downloader.view().explain(color!(0xff0000))
                } else {
                    self.jlc_downloader.view()
                }
            }
            TabId::DbBrowser => {
                if self.explain {
                    self.db_browser.view().explain(color!(0xff0000))
                } else {
                    self.db_browser.view()
                }
            }
            TabId::PartViewer => {
                if self.explain {
                    self.part_viewer.view().explain(color!(0xff0000))
                } else {
                    self.part_viewer.view()
                }
            }
        };
        // let content = iced::widget::Button::new("Click").on_press(MainWindowMsg::Nothing);

        //let content = column![h, v].into();
        toast::Manager::new(column![h,v], &self.toasts, MainWindowMsg::CloseToast).timeout(8).into()
    }
}

pub trait TabContent {
    type TabMessage;
    fn update(&mut self, msg: Self::TabMessage) -> Task<MainWindowMsg>;
    fn view(&self) -> Element<'_, MainWindowMsg> {
        iced::widget::Container::new(self.content())
            .width(Length::Fill)
            .height(Length::Fill)
            .align_x(Horizontal::Left)
            .align_y(Vertical::Top)
            .padding(16.0)
            .into()
    }
    fn content(&self) -> Element<'_, MainWindowMsg>;
}
