use crate::CosimoUi;
use crate::app_config::{CONFIG_PATH, load_app_config};
use crate::file_ops::portable_path;
use crate::localization::Localizer;
use crate::menu_model::{
    RecentDeckMenuLayout, RecentDeckMenuSlot, recent_deck_menu_item_names, recent_deck_menu_layout,
    recent_deck_paths_for_menu,
};
use std::path::Path;
use wxdragon::prelude::*;

pub(crate) fn set_menu_item_label(menu_bar: &MenuBar, item_id: Id, label: &str) {
    if let Some(item) = menu_bar.find_item(item_id) {
        item.set_label(label);
    }
}

fn file_menu_recent_insert_position(file_menu: &Menu) -> usize {
    let open_deck_id = CosimoUi::xrc_id("menu_open_deck");
    (0..file_menu.get_item_count())
        .find(|position| {
            file_menu
                .find_item_by_position(*position)
                .is_some_and(|item| item.get_item_id() == open_deck_id)
        })
        .map(|position| position + 1)
        .unwrap_or_else(|| file_menu.get_item_count().min(1))
}

fn is_recent_deck_menu_control(item: &MenuItem) -> bool {
    let item_id = item.get_item_id();
    item_id == CosimoUi::xrc_id("menu_recent_decks")
        || item_id == CosimoUi::xrc_id("menu_recent_deck_1")
        || item.get_sub_menu().is_some()
}

fn remove_recent_deck_menu_control(file_menu: &Menu) {
    loop {
        let position = file_menu_recent_insert_position(file_menu);
        if position >= file_menu.get_item_count() {
            break;
        }
        let Some(item) = file_menu.find_item_by_position(position) else {
            break;
        };
        if is_recent_deck_menu_control(&item) {
            file_menu.delete_item(&item);
        } else {
            break;
        }
    }
}

pub(crate) fn sync_recent_deck_menu(
    frame: Frame,
    localizer: Localizer,
    current_deck_path: Option<&Path>,
) {
    let recent_deck_paths = load_app_config(portable_path(CONFIG_PATH))
        .map(|config| recent_deck_paths_for_menu(&config, current_deck_path))
        .unwrap_or_default();
    let Some(menu_bar) = frame.get_menu_bar() else {
        return;
    };
    let Some(file_menu) = menu_bar.get_menu(0) else {
        return;
    };

    remove_recent_deck_menu_control(&file_menu);
    let insert_position = file_menu_recent_insert_position(&file_menu);

    match recent_deck_menu_layout(&recent_deck_paths) {
        RecentDeckMenuLayout::Hidden => {}
        RecentDeckMenuLayout::DirectItem(label) => {
            file_menu.insert(
                insert_position,
                CosimoUi::xrc_id("menu_recent_deck_1"),
                &label,
                "Open a recently used deck",
                ItemKind::Normal,
            );
        }
        RecentDeckMenuLayout::Submenu(slots) => {
            let recent_decks_menu = Menu::builder().build();
            for (item_name, slot) in recent_deck_menu_item_names().iter().zip(slots.iter()) {
                if let RecentDeckMenuSlot::Show(label) = slot {
                    recent_decks_menu.append(
                        CosimoUi::xrc_id(item_name),
                        label,
                        "Open a recently used deck",
                        ItemKind::Normal,
                    );
                }
            }
            file_menu.insert_submenu(
                insert_position,
                recent_decks_menu,
                localizer.recent_decks_menu_item(),
                "Open a recently used deck",
            );
        }
    }
}
