use super::*;
use iced::widget::text_editor;

impl Maolan {
    pub(super) fn handle_show_message(&mut self, show: &Show) -> Task<Message> {
        if !self.state.blocking_read().hw_loaded
            && matches!(
                show,
                Show::Save | Show::SaveAs | Show::SaveTemplateAs | Show::Open
            )
        {
            return Task::none();
        }
        {
            let mut state = self.state.blocking_write();
            state.ctrl = false;
            state.shift = false;
        }
        match show {
            Show::Save => {
                if let Some(path) = &self.session_dir {
                    return self.refresh_graphs_then_save(path.to_string_lossy().to_string());
                }
                Task::perform(
                    async {
                        AsyncFileDialog::new()
                            .set_title("Select folder to save session")
                            .set_directory("/tmp")
                            .pick_folder()
                            .await
                            .map(|handle| handle.path().to_path_buf())
                    },
                    Message::SaveFolderSelected,
                )
            }
            Show::SaveAs => Task::perform(
                async {
                    AsyncFileDialog::new()
                        .set_title("Select folder to save session")
                        .set_directory("/tmp")
                        .pick_folder()
                        .await
                        .map(|handle| handle.path().to_path_buf())
                },
                Message::SaveFolderSelected,
            ),
            Show::SaveTemplateAs => {
                self.state.blocking_write().template_save_dialog =
                    Some(crate::state::TemplateSaveDialog {
                        name: String::new(),
                    });
                self.modal = Some(Show::SaveTemplateAs);
                Task::none()
            }
            Show::Open => Task::perform(
                async {
                    AsyncFileDialog::new()
                        .set_title("Select folder to open session")
                        .set_directory("/tmp")
                        .pick_folder()
                        .await
                        .map(|handle| handle.path().to_path_buf())
                },
                Message::OpenFolderSelected,
            ),
            Show::AddTrack => {
                self.modal = Some(Show::AddTrack);
                self.add_track.set_available_templates(Vec::new());
                self.add_track.set_available_group_templates(Vec::new());
                Task::batch(vec![
                    Task::perform(
                        async { crate::gui::scan_track_templates() },
                        Message::TrackTemplatesLoaded,
                    ),
                    Task::perform(
                        async { crate::gui::scan_group_templates() },
                        Message::GroupTemplatesLoaded,
                    ),
                    iced::widget::operation::focus(crate::add_track::AddTrackView::name_input_id()),
                ])
            }
            Show::TrackPluginList => {
                self.modal = Some(Show::TrackPluginList);
                #[cfg(all(unix, not(target_os = "macos")))]
                self.selected_lv2_plugins.clear();
                self.selected_vst3_plugins.clear();
                self.selected_clap_plugins.clear();
                Task::none()
            }
            Show::GenerateAudio => {
                self.generate_audio_prompt_editor = text_editor::Content::new();
                self.generate_audio_tags_input.clear();
                self.generate_audio_cfg_scale_input =
                    maolan_generate::DEFAULT_CFG_SCALE.to_string();
                self.generate_audio_steps_input = 10;
                self.generate_audio_seconds_total_input = 180;
                self.generate_audio_in_progress = false;
                self.generate_audio_progress = 0.0;
                self.generate_audio_operation = None;
                self.modal = Some(Show::GenerateAudio);
                Task::none()
            }
            Show::ExportSettings => {
                self.modal = Some(Show::ExportSettings);
                Task::none()
            }
            Show::SessionMetadata => {
                self.modal = Some(Show::SessionMetadata);
                Task::none()
            }
            Show::Preferences => {
                #[cfg(any(target_os = "linux", target_os = "windows"))]
                {
                    let prefs = super::super::super::load_preferences();
                    {
                        let mut state = self.state.blocking_write();
                        Self::apply_preferred_devices_to_state(&mut state, &prefs);
                    }
                    self.modal = Some(Show::Preferences);
                    Task::perform(
                        async {
                            #[cfg(target_os = "linux")]
                            {
                                (
                                    crate::state::discover_alsa_output_devices(),
                                    crate::state::discover_alsa_input_devices(),
                                )
                            }
                            #[cfg(target_os = "windows")]
                            {
                                (
                                    crate::state::discover_windows_audio_devices(),
                                    crate::state::discover_windows_input_devices(),
                                )
                            }
                        },
                        |(output_devices, input_devices)| Message::PreferencesDevicesLoaded {
                            output_devices,
                            input_devices,
                        },
                    )
                }
                #[cfg(not(any(target_os = "linux", target_os = "windows")))]
                {
                    self.modal = Some(Show::Preferences);
                    Task::none()
                }
            }
            Show::AutosaveRecovery => {
                self.modal = Some(Show::AutosaveRecovery);
                Task::none()
            }
            Show::UnsavedChanges => {
                self.modal = Some(Show::UnsavedChanges);
                Task::none()
            }
            Show::About => {
                self.modal = Some(Show::About);
                Task::none()
            }
            Show::TrackColor { track_name } => {
                self.modal = Some(Show::TrackColor {
                    track_name: track_name.clone(),
                });
                Task::none()
            }
        }
    }
}
