//! UI actions for ordinary study-session controls.
//!
//! This module owns direct study control behaviour: starting ordinary passes,
//! revealing responses, applying ratings and confidence, flagging, deferring,
//! and ending the current pass. Menu dispatch and ready-list card management
//! live elsewhere.

use std::cell::RefCell;
use std::rc::Rc;

use cosimo::{PromptGuess, RecallFeedback};
use wxdragon::WxWidget;

use crate::app_config::ReviewAudioPolicy;
use crate::app_state::AppState;
use crate::dialog_support::{show_error_dialog_with_parent, show_info_dialog_with_parent};
use crate::ready_screen::{ready_screen_has_cards, render};
use crate::review_dialogs::show_cycle_stats_dialog;
use crate::review_input::RatingButton;
use crate::review_session::{ReviewCycleSummary, ReviewDeferralProgress, ReviewPhase};
use crate::review_ui::{ReadyCardListFocusAvailability, ReviewUi};

#[derive(Debug, Clone)]
pub(crate) enum ReviewDeferralUiAction {
    ContinueReview,
    ShowNoCardsReviewed,
    ShowSummary(ReviewCycleSummary),
}

pub(crate) fn review_deferral_ui_action(
    progress: ReviewDeferralProgress,
) -> ReviewDeferralUiAction {
    match progress {
        ReviewDeferralProgress::Continuing => ReviewDeferralUiAction::ContinueReview,
        ReviewDeferralProgress::Finished {
            completed_summary: Some(summary),
        } => ReviewDeferralUiAction::ShowSummary(summary),
        ReviewDeferralProgress::Finished {
            completed_summary: None,
        } => ReviewDeferralUiAction::ShowNoCardsReviewed,
    }
}

#[derive(Debug, Clone)]
pub(crate) enum ReviewStepUiAction {
    ContinueReview,
    ShowSummary(ReviewCycleSummary),
}

pub(crate) fn review_step_ui_action(
    cycle_summary: Option<ReviewCycleSummary>,
) -> ReviewStepUiAction {
    match cycle_summary {
        Some(cycle_summary) => ReviewStepUiAction::ShowSummary(cycle_summary),
        None => ReviewStepUiAction::ContinueReview,
    }
}

pub(crate) fn start_scheduled_study_from_ui(ui: &ReviewUi, state: &Rc<RefCell<AppState>>) {
    start_study_from_ui(ui, state, AppState::start_cycle);
}

pub(crate) fn force_start_study_from_ui(ui: &ReviewUi, state: &Rc<RefCell<AppState>>) {
    start_study_from_ui(ui, state, AppState::force_start_cycle);
}

pub(crate) fn review_flagged_cards_from_ui(ui: &ReviewUi, state: &Rc<RefCell<AppState>>) {
    start_study_from_ui(ui, state, AppState::review_flagged_cards);
}

fn start_study_from_ui(ui: &ReviewUi, state: &Rc<RefCell<AppState>>, start: fn(&mut AppState)) {
    start(&mut state.borrow_mut());
    render(ui, &state.borrow());
    show_pending_warning_dialog(ui, state);
}

fn show_pending_warning_dialog(ui: &ReviewUi, state: &Rc<RefCell<AppState>>) {
    let (localizer, warning) = {
        let mut state_ref = state.borrow_mut();
        (state_ref.localizer, state_ref.take_pending_warning_dialog())
    };
    if let Some(warning) = warning {
        show_info_dialog_with_parent(&ui.frame, localizer.warning_caption(), &warning);
    }
}

pub(crate) fn reveal_response_without_guess(ui: &ReviewUi, state: &Rc<RefCell<AppState>>) -> bool {
    if !matches!(state.borrow().session.phase(), ReviewPhase::Prompt) {
        return false;
    }

    state.borrow_mut().show_response(PromptGuess::NotAnswered);
    render(ui, &state.borrow());
    true
}

pub(crate) fn activate_rating(
    ui: &ReviewUi,
    state: &Rc<RefCell<AppState>>,
    rating_button: RatingButton,
) -> bool {
    let phase = state.borrow().session.phase();

    match phase {
        ReviewPhase::ReadyToStart => false,
        ReviewPhase::Prompt => {
            state
                .borrow_mut()
                .show_response(rating_button.prompt_guess());
            render(ui, &state.borrow());
            true
        }
        ReviewPhase::Response { .. } => {
            submit_feedback(ui, state, rating_button.recall_feedback());
            true
        }
    }
}

pub(crate) fn end_current_pass_from_ui(ui: &ReviewUi, state: &Rc<RefCell<AppState>>) -> bool {
    state.borrow().review_audio_player.borrow_mut().stop();
    let cycle_summary = state.borrow_mut().end_current_pass();

    match review_step_ui_action(cycle_summary) {
        ReviewStepUiAction::ShowSummary(cycle_summary) => {
            handle_cycle_summary(ui, state, cycle_summary);
            true
        }
        ReviewStepUiAction::ContinueReview => {
            render(ui, &state.borrow());
            false
        }
    }
}

pub(crate) fn submit_feedback(
    ui: &ReviewUi,
    state: &Rc<RefCell<AppState>>,
    feedback: RecallFeedback,
) {
    let cycle_summary = state
        .borrow_mut()
        .record_feedback_and_check_for_cycle_completion(feedback);

    match review_step_ui_action(cycle_summary) {
        ReviewStepUiAction::ShowSummary(cycle_summary) => {
            handle_cycle_summary(ui, state, cycle_summary)
        }
        ReviewStepUiAction::ContinueReview => render(ui, &state.borrow()),
    }
}

pub(crate) fn defer_current_review_card_from_ui(ui: &ReviewUi, state: &Rc<RefCell<AppState>>) {
    let localizer = state.borrow().localizer;
    let defer_result = { state.borrow_mut().defer_current_review_card() };
    match defer_result {
        Ok(outcome) => match review_deferral_ui_action(outcome) {
            ReviewDeferralUiAction::ShowSummary(cycle_summary) => {
                handle_cycle_summary(ui, state, cycle_summary)
            }
            ReviewDeferralUiAction::ShowNoCardsReviewed => {
                render(ui, &state.borrow());
                show_info_dialog_with_parent(
                    &ui.frame,
                    localizer.no_cards_reviewed_caption(),
                    localizer.no_cards_reviewed_message(),
                );
                ui.cycle_summary.set_focus();
            }
            ReviewDeferralUiAction::ContinueReview => {
                render(ui, &state.borrow());
            }
        },
        Err(error) => {
            show_error_dialog_with_parent(
                &ui.frame,
                localizer.could_not_edit_card_caption(),
                &error,
            );
            render(ui, &state.borrow());
        }
    }
}

fn handle_cycle_summary(
    ui: &ReviewUi,
    state: &Rc<RefCell<AppState>>,
    cycle_summary: ReviewCycleSummary,
) {
    let play_summary_cue = {
        let state_ref = state.borrow();
        state_ref.settings.review_audio_policy == ReviewAudioPolicy::Automatic
            && state_ref.settings.review_audio_cues
    };
    if play_summary_cue {
        state
            .borrow()
            .review_audio_player
            .borrow_mut()
            .play_summary_cue();
    } else {
        state.borrow().review_audio_player.borrow_mut().stop();
    }
    let localizer = state.borrow().localizer;
    let (deck_path, review_db_path) = {
        let state_ref = state.borrow();
        (
            state_ref.deck_path.clone(),
            state_ref.review_db_path.clone(),
        )
    };
    if show_cycle_stats_dialog(
        ui.frame,
        localizer,
        cycle_summary,
        &deck_path,
        &review_db_path,
    ) {
        state.borrow_mut().restart_cycle();
        let state_ref = state.borrow();
        render(ui, &state_ref);
        ui.focus_ready_card_list(ReadyCardListFocusAvailability::for_has_cards(
            ready_screen_has_cards(&state_ref),
        ));
    } else {
        ui.frame.close(false);
    }
}
