use crate::ui::main_window::{MainWindowMsg, TabContent};
use crate::utils::step_downloader::{self as downloader, FetchResultItem, SearchResultItem};
use crate::widgets::toast;
#[allow(unused_imports)]
use anyhow::Result;
use iced::widget::{Row, button, keyed_column};
use iced::{Element, Length, Task, alignment::Horizontal, widget::Column};
use tokio::io::AsyncWriteExt;
use tracing::info;

pub struct JlcDownloader {
    search_word: String,
    search_status: String,
    search_available: bool,
    search_index: usize,
    result_list: Vec<SearchResultItem>,
    fetch_list: Vec<FetchResultItem>,
    msg_disp: String,
    step_data: String,
    theme: iced::Theme,
    item_clickable: bool,
    current_step_content: String,
    current_step_name: String,
    pub step_save_dir: String,
}
impl JlcDownloader {
    pub fn set_theme(&mut self, theme: iced::Theme) {
        self.theme = theme;
    }
    fn fetch_something(&mut self) -> Task<MainWindowMsg> {
        info!("Fetching data : {}", self.search_index);
        self.msg_disp = format!("Fetching : {}", self.search_index);
        return if self.search_index < self.result_list.len() {
            Task::perform(
                downloader::fetch_item(self.result_list[self.search_index].clone()),
                |x| match x {
                    Ok(v) => MainWindowMsg::JlcDownloader(JlcDownloaderMsg::ItemFetchResult(v)),
                    Err(e) => MainWindowMsg::JlcDownloader(JlcDownloaderMsg::ItemFetchError(
                        e.to_string(),
                    )),
                },
            )
        } else {
            Task::none()
        };
    }
    fn create_fetched_item_button(
        &self,
        item: &FetchResultItem,
        width: u32,
    ) -> iced::widget::Button<'_, MainWindowMsg> {
        let theme = self.theme.clone();
        let palette = theme.extended_palette();
        let info = iced::widget::column![
            iced::widget::text(format!("元件：{}", item.name)),
            iced::widget::text(format!("编号：{}", item.code)),
            iced::widget::text(format!("模型：{}", item.model)),
        ]
        .width(Length::FillPortion(2));
        let mut btn_content = Row::new().spacing(10);
        for img in item.imgs.clone().iter() {
            btn_content = btn_content
                .push(iced::widget::Image::new(img.clone()).width(Length::FillPortion(1)));
        }
        btn_content = btn_content.push(info);
        if self.item_clickable {
            let attr = DownloadAttr {
                name: item.name.clone(),
                id: item.model_id.clone(),
            };
            iced::widget::Button::new(btn_content).on_press(MainWindowMsg::JlcDownloader(
                JlcDownloaderMsg::PartClicked(attr),
            ))
        } else {
            iced::widget::Button::new(btn_content)
        }
    }
}
impl Default for JlcDownloader {
    fn default() -> Self {
        Self {
            search_word: "".to_string(),
            search_status: "".to_string(),
            search_available: true,
            search_index: 0,
            result_list: vec![],
            fetch_list: vec![],
            msg_disp: "".to_string(),
            step_data: "".to_string(),
            theme: Default::default(),
            item_clickable: true,
            current_step_content: "".to_string(),
            current_step_name: "".to_string(),
            step_save_dir: String::new(),
        }
    }
}
#[allow(dead_code)]
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum JlcDownloaderMsg {
    Nothing,
    KeywordChanged(String),
    ItemFetchResult(FetchResultItem),
    ItemFetchError(String),
    KeywordSearchResult(Vec<SearchResultItem>),
    KeywordSearchError(String),
    PartClicked(DownloadAttr),
    StepFetched(String),
    StepFetchErr(String),
    OpenDatasheet(String),
    SearchPart,
}
#[derive(Debug, Clone, PartialEq, Eq)]
struct DownloadAttr {
    name: String,
    id: String,
}
impl TabContent for JlcDownloader {
    type TabMessage = JlcDownloaderMsg;

    fn update(&mut self, msg: Self::TabMessage) -> Task<MainWindowMsg> {
        match msg {
            JlcDownloaderMsg::Nothing => {
                info!("JlcDownloaderMsg::Nothing");
            }
            JlcDownloaderMsg::KeywordChanged(k) => {
                self.search_word = k;
                self.search_status.clear();
            }
            JlcDownloaderMsg::SearchPart => {
                self.search_status = "Searching...".to_string();
                self.search_index = 0;
                self.search_available = false;
                self.fetch_list.clear();
                self.result_list.clear();
                return Task::perform(
                    downloader::search_keyword(self.search_word.clone(), 1, 20),
                    |x| match x {
                        Ok(v) => {
                            MainWindowMsg::JlcDownloader(JlcDownloaderMsg::KeywordSearchResult(v))
                        }
                        Err(e) => {
                            let e = format!("{e:?}");
                            MainWindowMsg::JlcDownloader(JlcDownloaderMsg::KeywordSearchError(e))
                        }
                    },
                );
            }
            JlcDownloaderMsg::KeywordSearchResult(rest) => {
                self.search_status.clear();
                self.search_available = true;
                self.result_list.clear();
                self.result_list = rest;
                self.search_index = 0;
                return self.fetch_something();
            }
            JlcDownloaderMsg::KeywordSearchError(e) => {
                self.search_status = e;
                self.search_available = true;
            }
            JlcDownloaderMsg::ItemFetchResult(item) => {
                self.fetch_list.push(item);
                //开始fetch下一条
                self.search_index += 1;
                return self.fetch_something();
            }
            JlcDownloaderMsg::ItemFetchError(e) => {
                info!("JlcDownloaderMsg::ItemFetchError({:?})", e);
                self.search_index += 1;
                return self.fetch_something();
            }
            JlcDownloaderMsg::PartClicked(id) => {
                self.current_step_name = id.name.clone();
                info!("JlcDownloaderMsg::PartClicked {:?}", id);
                self.item_clickable = false;
                return Task::perform(downloader::download_step(id.id), |x| match x {
                    Ok(s) => MainWindowMsg::JlcDownloader(JlcDownloaderMsg::StepFetched(s)),
                    Err(e) => MainWindowMsg::JlcDownloader(JlcDownloaderMsg::ItemFetchError(
                        e.to_string(),
                    )),
                });
            }
            JlcDownloaderMsg::StepFetched(s) => {
                // MainWindowMsg::Toast(toast::Toast{title:"下载成功".into(),body:format!("{}的模型下载成功",s),status:toast::Status::Success});
                self.item_clickable = true;
                let model_name = self.current_step_name.clone();
                let mut step_dir = String::new();
                if let Ok(dir) = crate::utils::app_settings::get_step_dir() {
                    step_dir = dir;
                } else {
                    step_dir = self.step_save_dir.clone();
                }
                return Task::perform(
                    async move {
                        tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;
                        let file_path = format!("{step_dir}\\{model_name}.step");
                        if let Ok(mut f) =  tokio::fs::File::create(file_path.clone()).await{
                            if f.write_all(s.as_str().as_bytes()).await.is_ok(){
                                return (true,file_path);
                            }
                        }
                        return (false,file_path)
                    },
                     |(rst,path)| {
                         let title = match rst{
                             true=>"下载成功".to_string(),
                             false=>"下载失败".to_string(),
                         };
                         let body = match rst{
                             true=>format!("Step模型存储到{path}"),
                             false=> "Step模型下载成功但无法保存，请检查是否有写入权限".to_string(),
                         };
                         let status = match rst{
                             true=>toast::Status::Success,
                             false=>toast::Status::Danger,
                         };
                        MainWindowMsg::Toast(toast::Toast {
                            title,
                            body,
                            status
                        })
                    },
                );
            }
            JlcDownloaderMsg::StepFetchErr(e) => {
                self.item_clickable = true;
                let model_name = self.current_step_name.clone();
                return Task::perform(
                    async { tokio::time::sleep(tokio::time::Duration::from_millis(10)) },
                    move |_| {
                        MainWindowMsg::Toast(toast::Toast {
                            title: "下载失败".into(),
                            body: format!("{}的模型下载失败", model_name),
                            status: toast::Status::Danger,
                        })
                    },
                );
            }
            JlcDownloaderMsg::OpenDatasheet(url) => {
                todo!("To open the url!");
            }
        }
        Task::none()
    }

    fn content(&self) -> iced::Element<'_, MainWindowMsg> {
        let h = iced::widget::row![
            iced::widget::text_input("元件名或嘉立创编号", &self.search_word)
                .on_input(MainWindowMsg::SearchKeywordChanged)
                .width(iced::FillPortion(6)),
            if !self.search_available {
                iced::widget::button("搜索").width(iced::FillPortion(1))
            } else {
                iced::widget::button("搜索")
                    .width(iced::FillPortion(1))
                    .on_press(MainWindowMsg::JlcDownloader(JlcDownloaderMsg::SearchPart))
            },
            iced::widget::horizontal_space().width(iced::FillPortion(1)),
        ];
        let mut results = iced::widget::column![];
        for item in self.fetch_list.iter() {
            results = results.push(self.create_fetched_item_button(&item, 1000));
        }

        let mut logs = iced::widget::column!["预览暂不可用，期待后期iced更新",];
        let body = iced::widget::row![
            iced::widget::column![
                iced::widget::text(self.msg_disp.clone()).height(Length::Shrink),
                iced::widget::scrollable(iced::widget::column![results.spacing(10),]),
            ]
            .width(iced::Length::FillPortion(6)),
            // logs.width(iced::Length::FillPortion(4)),
            iced::widget::scrollable(logs).width(iced::Length::FillPortion(4)),
        ]
        .height(Length::Fill);
        Column::new()
            .align_x(Horizontal::Left)
            .width(Length::Fill)
            .height(Length::Fill)
            .push(h)
            .push(body)
            .into()
    }
}
