use crate::dialog_support::is_dialog_accept_key;

pub(crate) fn is_ready_list_delete_key(key_code: Option<i32>) -> bool {
    matches!(key_code, Some(127))
}

pub(crate) fn is_ready_screen_refresh_key(key_code: Option<i32>) -> bool {
    matches!(key_code, Some(344) | Some(116))
}

pub(crate) fn is_ready_list_details_key(
    unicode_key: Option<i32>,
    key_code: Option<i32>,
    alt_down: bool,
) -> bool {
    alt_down && is_dialog_accept_key(unicode_key, key_code)
}

pub(crate) fn is_ready_list_toggle_suspension_key(
    unicode_key: Option<i32>,
    key_code: Option<i32>,
    control_down: bool,
) -> bool {
    control_down
        && (matches!(
            unicode_key
                .and_then(|key| u32::try_from(key).ok())
                .and_then(char::from_u32),
            Some('s' | 'S')
        ) || matches!(key_code, Some(83) | Some(19)))
}

pub(crate) fn is_toggle_flag_key(
    unicode_key: Option<i32>,
    key_code: Option<i32>,
    control_down: bool,
) -> bool {
    control_down
        && (matches!(
            unicode_key
                .and_then(|key| u32::try_from(key).ok())
                .and_then(char::from_u32),
            Some('f' | 'F')
        ) || matches!(key_code, Some(70) | Some(6)))
}

pub(crate) fn is_toggle_deferral_key(
    unicode_key: Option<i32>,
    key_code: Option<i32>,
    control_down: bool,
) -> bool {
    control_down
        && (matches!(
            unicode_key
                .and_then(|key| u32::try_from(key).ok())
                .and_then(char::from_u32),
            Some('d' | 'D')
        ) || matches!(key_code, Some(68) | Some(4)))
}

pub(crate) fn is_toggle_review_audio_key(
    unicode_key: Option<i32>,
    key_code: Option<i32>,
    control_down: bool,
) -> bool {
    control_down
        && (matches!(
            unicode_key
                .and_then(|key| u32::try_from(key).ok())
                .and_then(char::from_u32),
            Some('p' | 'P')
        ) || matches!(key_code, Some(80) | Some(16)))
}

pub(crate) fn is_ready_list_toggle_reversible_key(
    unicode_key: Option<i32>,
    key_code: Option<i32>,
    control_down: bool,
) -> bool {
    control_down
        && (matches!(
            unicode_key
                .and_then(|key| u32::try_from(key).ok())
                .and_then(char::from_u32),
            Some('r' | 'R')
        ) || matches!(key_code, Some(82) | Some(18)))
}

pub(crate) fn is_edit_revealed_card_key(unicode_key: Option<i32>, key_code: Option<i32>) -> bool {
    matches!(
        unicode_key
            .and_then(|key| u32::try_from(key).ok())
            .and_then(char::from_u32),
        Some('e' | 'E')
    ) || matches!(key_code, Some(69))
}

pub(crate) fn is_reveal_response_key(unicode_key: Option<i32>, key_code: Option<i32>) -> bool {
    matches!(
        unicode_key
            .and_then(|key| u32::try_from(key).ok())
            .and_then(char::from_u32),
        Some(' ')
    ) || matches!(key_code, Some(32))
}

pub(crate) fn key_to_digit(unicode_key: Option<i32>, key_code: Option<i32>) -> Option<u8> {
    if let Some(value) = unicode_key {
        match char::from_u32(value as u32) {
            Some('0') => return Some(0),
            Some('1') => return Some(1),
            Some('2') => return Some(2),
            Some('3') => return Some(3),
            Some('4') => return Some(4),
            _ => {}
        }
    }

    match key_code {
        Some(48) => Some(0),
        Some(49) => Some(1),
        Some(50) => Some(2),
        Some(51) => Some(3),
        Some(52) => Some(4),
        _ => None,
    }
}

pub(crate) fn is_plain_tab_key(
    key_code: Option<i32>,
    control_down: bool,
    shift_down: bool,
) -> bool {
    key_code == Some(9) && !control_down && !shift_down
}

pub(crate) fn is_shift_tab_key(
    key_code: Option<i32>,
    control_down: bool,
    shift_down: bool,
) -> bool {
    key_code == Some(9) && !control_down && shift_down
}

pub(crate) fn is_control_enter_key(
    unicode_key: Option<i32>,
    key_code: Option<i32>,
    control_down: bool,
) -> bool {
    control_down && is_dialog_accept_key(unicode_key, key_code)
}

pub(crate) fn card_batch_fields_are_complete(prompt: &str, response: &str) -> bool {
    !prompt.trim().is_empty() && !response.trim().is_empty()
}
