pub(crate) mod command_runner;
pub(crate) mod commit;
pub mod editor;
pub mod project_search;
pub(crate) mod save_state;
pub(crate) mod extension_config;
pub mod file_selector;
pub(crate) mod git_branches;
pub(crate) mod git_history;
pub(crate) mod git_history_editor;
pub(crate) mod git_pull;
pub(crate) mod issue_view;
pub(crate) mod log_view;
// legacy SearchReplace view removed — editor now hosts expanded project search
pub(crate) mod task_archive;
pub mod terminal;

use ratatui::{Frame, layout::Rect};

use crate::input;
use crate::operation::{Event, Operation};
use crate::theme::Theme;
use crate::settings::Settings;

/// Whether a view is a primary working context or a temporary overlay.
///
/// - **Primary** views (Editor, Terminal, CommitWindow, GitHistory) represent the
///   user's main working context. When opening a modal the current primary is
///   stashed so it can be restored when the modal closes.
/// - **Modal** views (FileSelector, CommandRunner, LogView, SearchReplace,
///   ExtensionConfig) are overlays. Pressing `Esc` while in a modal view returns
///   to the stashed primary view.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ViewKind {
    Primary,
    Modal,
}

/// Every full-screen view implements this trait.
///
/// # Responsibilities
///
/// - `handle_key`       — translate raw input into operations (no mutation)
/// - `handle_mouse`     — translate mouse events into operations (default no-op)
/// - `handle_operation` — apply operations the view owns; emit an event on success
/// - `render`           — draw the current state to the terminal frame
///
/// Views own their slice of state.  Nobody mutates a view's internals except
/// the view itself, through `handle_operation`.
pub trait View {
    /// The kind of this view: [`ViewKind::Primary`] or [`ViewKind::Modal`].
    ///
    /// Used by the escape logic to decide whether to revert to the last primary
    /// view or to ignore the key press.
    const KIND: ViewKind;
    /// Translate a key event into zero or more operations.
    /// Must not mutate `self` — use `handle_operation` for that.
    fn handle_key(&self, key: input::KeyEvent) -> Vec<Operation>;

    /// Translate a mouse event into zero or more operations.
    /// Default implementation is a no-op; views that support mouse override this.
    fn handle_mouse(&self, _mouse: input::MouseEvent) -> Vec<Operation> {
        vec![]
    }

    /// Apply a single operation if it is relevant to this view.
    ///
    /// Returns `Some(event)` if the operation was applied (so the event loop
    /// can broadcast the resulting event to subscribers), or `None` if this
    /// view does not own the operation.
    fn handle_operation(&mut self, op: &Operation, settings: &Settings) -> Option<Event>;

    /// Save the current state of the view before it is closed.
    fn save_state(&mut self, app_state: &mut crate::app_state::AppState);

    /// Draw the view into the provided `area` of the current frame.
    fn render(&self, frame: &mut Frame, area: Rect, theme: &Theme);

    /// Populate the global status bar with view-specific content.
    ///
    /// The default implementation is a no-op; views that want to surface
    /// information in the status bar override this.
    fn status_bar(&self, _state: &crate::app_state::AppState, _bar: &mut crate::widgets::status_bar::StatusBarBuilder) {}
}