use std::fmt::write;

use egui::{Color32, RichText, Sense, Vec2};
use song_list_nav::SearchType;
use xmpd_cache::DlStatus;
use xmpd_manifest::{song::Song, store::BaseStore};
use super::{CompGetter, CompUi};

pub mod song_list_nav;

#[derive(Debug, Default)]
pub struct SongList {
    selected_song_id: uuid::Uuid
}

component_register!(SongList);

impl CompUi for SongList {
    fn draw(ui: &mut egui::Ui, state: &mut crate::GuiState) -> crate::Result<()> {
        egui::ScrollArea::vertical()
            .id_source("song_list")
            .drag_to_scroll(false)
            .show(ui, |ui| {
                ui.vertical(|ui| {
                    ui.add_space(3.0);
                    let pid = {handle_error_ui!(super::left_nav::LeftNav::get()).selected_playlist_id.clone()};
                    match pid {
                        None => {
                            let mut songs: Vec<_> = state.manifest.store().get_songs().iter().collect();
                            songs.sort_by(|a, b| {
                                let a = a.1.name().to_lowercase();
                                let b = b.1.name().to_lowercase();
                                a.cmp(&b)
                            });

                            for (sid, song) in songs {
                                let query = {handle_error_ui!(song_list_nav::SongListNav::get()).parse_search()}.clone();
                                let should_display = match query {
                                    SearchType::Source(s) if !s.is_empty() => format!("{:?}", &song.source_type()).to_lowercase().contains(&s),
                                    SearchType::Author(s) if !s.is_empty() => song.author().to_lowercase().contains(&s),
                                    SearchType::Name(s) if !s.is_empty() =>  song.name().to_owned().contains(&s),
                                    _ => true
                                };
                                if should_display {
                                    display_song_tab(ui, sid, song);
                                }
                            }
                        }
                        Some(pid) => {
                            if let Some(playlist) = state.manifest.store().get_playlist(&pid) {
                                let mut songs = Vec::new();
                                for sid in playlist.songs() {
                                    if let Some(song) = state.manifest.store().get_song(&sid) {
                                        songs.push((sid, song));
                                    }
                                }
                                songs.sort_by(|a, b| {
                                    let a = a.1.name().to_lowercase();
                                    let b = b.1.name().to_lowercase();
                                    a.cmp(&b)
                                });
                                let query = {handle_error_ui!(song_list_nav::SongListNav::get()).parse_search()}.clone();
                                for (sid, song) in songs {
                                    let should_display = match query {
                                        SearchType::Source(ref s) if !s.is_empty() => format!("{:?}", &song.source_type()).to_lowercase().contains(s),
                                        SearchType::Author(ref s) if !s.is_empty() => song.author().to_lowercase().contains(s),
                                        SearchType::Name(ref s) if !s.is_empty() =>  song.name().to_owned().contains(s),
                                        _ => true
                                    };
                                    if should_display {
                                        display_song_tab(ui, sid, song); 
                                    }
                                }
                            }
                        }
                    }
                    
                });
        });
        Ok(())
    }
}

fn display_song_tab(ui: &mut egui::Ui, sid: &uuid::Uuid, song: &Song) {
    let theme = handle_error_ui!(xmpd_settings::Settings::get()).theme.clone();
    ui.horizontal(|ui| {
        let mut clicked = ui.add(
            egui::Image::new(crate::data::NOTE_ICON)
                .tint(theme.accent_color)
                .sense(Sense::click())
                .fit_to_exact_size(Vec2::new(32.0, 32.0))
        ).clicked();

        ui.vertical(|ui| {
            let selected_song_id = {handle_error_ui!(SongList::get()).selected_song_id};
            let label = if selected_song_id == *sid {
                ui.label(
                    RichText::new(song.name())
                        .color(theme.accent_color)
                )
            } else {
                ui.label(
                    RichText::new(song.name())
                        .color(theme.text_color)
                )
            };

            if label.clicked() {
                clicked = true;
            }
            ui.monospace(
                RichText::new(format!("By {}", song.author()))
                    .color(theme.dim_text_color)
                    .size(10.0)
            );

        });
        
        ui.with_layout(egui::Layout::right_to_left(egui::Align::RIGHT), |ui| {
            ui.add_space(3.0);
            let status = {
                handle_error_ui!(xmpd_cache::Cache::get()).get_cached_song_status(&sid).clone()
            };
            match status {
                Some(DlStatus::Done(p)) => {
                    let img = ui.add(
                        egui::Image::new(crate::data::CHECK_ICON)
                            .tint(Color32::LIGHT_GREEN)
                            .sense(Sense::hover())
                            .fit_to_exact_size(Vec2::new(16.0, 16.0))
                    );

                    img.on_hover_ui(|ui| {
                        ui.label(format!("Path: {p}"));
                    });
                }
                Some(DlStatus::Downloading) => {
                    ui.add(
                        egui::Spinner::new()
                            .color(theme.accent_color)
                            .size(16.0)
                    );
                }
                Some(DlStatus::Error(e)) => {
                    let img = ui.add(
                        egui::Image::new(crate::data::WARN_ICON)
                            .tint(Color32::LIGHT_YELLOW)
                            .sense(Sense::hover())
                            .fit_to_exact_size(Vec2::new(16.0, 16.0))
                    );
                    img.on_hover_ui(|ui| {
                        ui.label(e);
                    });
                }
                None => {
                    let img = ui.add(
                        egui::Image::new(crate::data::DL_ICON)
                            .tint(theme.accent_color)
                            .sense(Sense::click())
                            .fit_to_exact_size(Vec2::new(16.0, 16.0))
                    );
                    if img.clicked() {
                        handle_error_ui!(xmpd_cache::Cache::get()).download_to_cache(sid.clone(), song.clone())
                    }
                }
            }
        });
        if clicked {
            handle_error_ui!(SongList::get()).selected_song_id = sid.clone();
        }
    });
    
    ui.separator();
}