use std::path::{Path, PathBuf};

use crate::app_config::{AppConfig, MAX_RECENT_DECKS};
use crate::localization::Localizer;

pub(crate) struct TopLevelMenuLabel {
    pub(crate) position: usize,
    pub(crate) label: &'static str,
}

pub(crate) struct MenuItemLabel {
    pub(crate) xrc_name: &'static str,
    pub(crate) label: &'static str,
}

pub(crate) struct SubmenuLabel {
    pub(crate) xrc_name: &'static str,
    pub(crate) label: &'static str,
}

pub(crate) fn localized_top_level_menu_labels(localizer: Localizer) -> [TopLevelMenuLabel; 4] {
    [
        TopLevelMenuLabel {
            position: 0,
            label: localizer.file_menu(),
        },
        TopLevelMenuLabel {
            position: 1,
            label: localizer.cards_menu(),
        },
        TopLevelMenuLabel {
            position: 2,
            label: localizer.view_menu(),
        },
        TopLevelMenuLabel {
            position: 3,
            label: localizer.help_menu(),
        },
    ]
}

pub(crate) fn localized_menu_item_labels(localizer: Localizer) -> [MenuItemLabel; 32] {
    [
        MenuItemLabel {
            xrc_name: "menu_open_deck",
            label: localizer.open_deck_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_options",
            label: localizer.options_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_deck_properties",
            label: localizer.deck_properties_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_edit_deck_properties",
            label: localizer.edit_deck_properties_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_learning_dashboard",
            label: localizer.learning_dashboard_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_scrub_review_database",
            label: localizer.scrub_review_database_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_reclaim_database_space",
            label: localizer.reclaim_database_space_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_quit",
            label: localizer.quit_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_add_card",
            label: localizer.add_card_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_add_card_batch",
            label: localizer.add_card_batch_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_edit_card",
            label: localizer.edit_selected_card_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_remove_card",
            label: localizer.remove_selected_card_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_toggle_card_suspension",
            label: localizer.suspend_selected_card_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_toggle_card_flag",
            label: localizer.flag_selected_card_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_review_flagged_cards",
            label: localizer.review_flagged_cards_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_toggle_card_deferral",
            label: localizer.defer_selected_card_until_tomorrow_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_toggle_card_reversal",
            label: localizer.make_selected_card_reversible_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_toggle_card_reversal_exclusion",
            label: localizer.mark_selected_card_non_reversible_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_make_eligible_cards_reversible",
            label: localizer.make_eligible_cards_reversible_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_undo_last_bulk_reversal",
            label: localizer.undo_last_bulk_reversal_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_sort_deck_order",
            label: localizer.sort_deck_order_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_sort_next_scheduled",
            label: localizer.sort_next_scheduled_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_sort_last_reviewed",
            label: localizer.sort_last_reviewed_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_sort_prompt_text",
            label: localizer.sort_prompt_text_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_sort_response_text",
            label: localizer.sort_response_text_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_sort_estimated_recall",
            label: localizer.sort_estimated_recall_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_sort_ascending",
            label: localizer.sort_ascending_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_sort_descending",
            label: localizer.sort_descending_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_user_guide",
            label: localizer.user_guide_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_report_bug",
            label: localizer.report_bug_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_project_wiki",
            label: localizer.project_wiki_menu_item(),
        },
        MenuItemLabel {
            xrc_name: "menu_about",
            label: localizer.about_menu_item(),
        },
    ]
}

pub(crate) fn localized_submenu_labels(localizer: Localizer) -> [SubmenuLabel; 1] {
    [SubmenuLabel {
        xrc_name: "menu_recent_decks",
        label: localizer.recent_decks_menu_item(),
    }]
}

pub(crate) fn recent_deck_menu_item_names() -> [&'static str; MAX_RECENT_DECKS] {
    [
        "menu_recent_deck_1",
        "menu_recent_deck_2",
        "menu_recent_deck_3",
        "menu_recent_deck_4",
        "menu_recent_deck_5",
        "menu_recent_deck_6",
        "menu_recent_deck_7",
        "menu_recent_deck_8",
    ]
}

#[derive(Debug, PartialEq, Eq)]
pub(crate) enum RecentDeckMenuSlot {
    Show(String),
    Hide,
}

#[derive(Debug, PartialEq, Eq)]
pub(crate) enum RecentDeckMenuLayout {
    Hidden,
    DirectItem(String),
    Submenu([RecentDeckMenuSlot; MAX_RECENT_DECKS]),
}

pub(crate) fn recent_deck_menu_slots(
    recent_deck_paths: &[PathBuf],
) -> [RecentDeckMenuSlot; MAX_RECENT_DECKS] {
    std::array::from_fn(|index| {
        recent_deck_paths
            .get(index)
            .map(|deck_path| {
                RecentDeckMenuSlot::Show(recent_deck_menu_item_label(index, deck_path))
            })
            .unwrap_or(RecentDeckMenuSlot::Hide)
    })
}

pub(crate) fn recent_deck_menu_layout(recent_deck_paths: &[PathBuf]) -> RecentDeckMenuLayout {
    match recent_deck_paths {
        [] => RecentDeckMenuLayout::Hidden,
        [deck_path] => {
            RecentDeckMenuLayout::DirectItem(single_recent_deck_menu_item_label(deck_path))
        }
        _ => RecentDeckMenuLayout::Submenu(recent_deck_menu_slots(recent_deck_paths)),
    }
}

pub(crate) fn recent_deck_paths_for_menu(
    config: &AppConfig,
    current_deck_path: Option<&Path>,
) -> Vec<PathBuf> {
    let current_deck_path = current_deck_path.or(config.last_open_deck_path.as_deref());
    config
        .recent_deck_paths
        .iter()
        .filter(|deck_path| Some(deck_path.as_path()) != current_deck_path)
        .cloned()
        .collect()
}

pub(crate) fn single_recent_deck_menu_item_label(deck_path: &Path) -> String {
    deck_path.display().to_string().replace('&', "&&")
}

pub(crate) fn recent_deck_menu_item_label(index: usize, deck_path: &Path) -> String {
    format!(
        "{}. {}",
        index + 1,
        deck_path.display().to_string().replace('&', "&&")
    )
}
