// `crate::` means from the crate root (absolute path). We re-exported StatusSummary in git/mod.rs,
// so crate::git::StatusSummary points directly to that type.
use crate::git::StatusSummary;
use crate::config::ThemeConfig;
use std::collections::HashMap;

#[derive(Debug, Clone)] // Debug lets you println!("{:?}", Clone lets you duplicate
pub struct AppState {
    pub running: bool, // whether the app should keep running
    pub theme: ThemeConfig, // Color theme configuration
    pub last_status: String, // last raw status output (placeholder)
    pub status_summary: StatusSummary,
    pub status_lines: Vec<String>,
    pub status_entries: Vec<crate::git::parsers::status::StatusEntry>,
    pub status_selected: usize,
    pub status_selected_path: String,
    pub last_diff_path: String,
    pub last_diff: String,
    pub last_diff_truncated: bool,
    pub last_diff_total: usize,
    pub last_diff_fetched_at: Option<String>,
    pub diff_mode: DiffMode,
    pub diff_parsed: crate::git::DiffParseResult,
    pub show_help: bool,
    pub repo_path: String,
    pub last_status_error: Option<String>,
    pub error_guidance: Option<crate::app::error_guidance::ErrorGuidance>,
    pub focus: FocusPane,
    pub key_help: Vec<KeyHelp>,
    pub last_refreshed: Option<String>,
    pub refreshing: bool,
    pub last_refresh_time: Option<std::time::Instant>,
    pub help_selected: usize, // which help item is highlighted when help is open
    pub detail_scroll: usize, // vertical scroll offset in detail pane
    pub detail_scroll_x: usize, // horizontal scroll offset in detail pane
    pub current_branch: String, // current git branch name
    // Multi-select for batch operations
    pub selected_files: std::collections::HashSet<String>,
    // Branch list
    pub branches: Vec<BranchEntry>,
    pub branch_selected: usize,
    // Commit log
    pub commits: Vec<CommitEntry>,
    pub commit_selected: usize,
    // Commit message input
    pub commit_input: String,
    pub commit_mode: bool, // true when in commit message input mode
    pub amend_mode: bool, // true when amending (vs. new commit)
    // Amend-specific fields
    pub amend_author_name: String,
    pub amend_author_email: String,
    pub last_commit_info: Option<LastCommitInfo>,
    pub amend_editing_field: Option<AmendField>, // Which field is being edited (if any)
    pub commit_template: Option<String>, // commit message template from config
    // Feedback message
    pub feedback_message: Option<String>,
    // Status filter
    pub status_filter: String,
    pub filter_mode: bool,
    // Per-file scroll offsets
    pub file_scrolls: HashMap<String, (usize, usize)>, // path -> (y, x)
    // Stash list
    pub stashes: Vec<StashEntry>,
    pub stash_selected: usize,
    // Branch create mode
    pub branch_create_mode: bool,
    pub branch_name_input: String,
    // Stash creation
    pub stash_create_mode: bool,
    pub stash_message_input: String,
    // Hunk navigation
    pub hunks: Vec<(usize, usize)>,
    pub hunk_selected: usize,
    // Word-diff mode
    pub word_diff: bool,
    // Line-level staging: selected line indices in current diff
    pub selected_lines: std::collections::HashSet<usize>,
    pub line_select_mode: bool,
    // Tags
    pub tags: Vec<TagEntry>,
    pub tag_selected: usize,
    // Delta availability
    pub has_delta: bool,
    pub use_delta: bool,
    // Diff context lines
    pub diff_context: usize,
    // Whitespace mode
    pub ignore_whitespace: bool,
    // Side-by-side view
    pub side_by_side: bool,
    // File tree view
    pub tree_view: bool,
    // Reflog
    pub reflog_entries: Vec<ReflogEntry>,
    pub reflog_selected: usize,
    // Commit details
    pub commit_detail: Option<String>,
    // File history mode (viewing log for a specific file)
    pub file_history_path: Option<String>,
    // Log filter (future: filter commits by author/message)
    #[allow(dead_code)]
    pub log_filter: String,
    #[allow(dead_code)]
    pub log_filter_mode: bool,
    // Show graph in log
    pub log_graph: bool,
    pub log_graph_text: String,
    // Log action menu
    pub log_action_menu: bool,
    pub log_action_selected: usize,
    pub log_action_commit_hash: Option<String>,
    // Confirm modal (generic)
    pub confirm_action: Option<crate::app::actions::Action>,
    pub confirm_message: Option<String>,
    // Remotes
    #[allow(dead_code)]
    pub remotes: Vec<RemoteEntry>,
    #[allow(dead_code)]
    pub remote_selected: usize,
    // Command palette
    pub command_palette: bool,
    pub palette_input: String,
    pub palette_selected: usize,
    // Multi-select in log for rebase
    pub log_selected_hashes: std::collections::HashSet<String>,
    pub rebase_base: Option<String>,
    // Async operations
    pub async_tasks: Vec<AsyncTask>,
    // Themes
    pub available_themes: Vec<String>,
    #[allow(dead_code)]
    pub font_family: Option<String>,
    #[allow(dead_code)]
    pub font_size: Option<u16>,
    pub theme_picker: bool,
    pub theme_picker_selected: usize,
    pub theme_preview_prior: Option<ThemeConfig>,
    // Diff rendering
    pub load_full_diff: bool,
    pub diff_focus: bool,
    // Reset confirmation
    pub reset_pending: Option<String>,
    // Op indicator/log
    pub op_status: Option<String>,
    pub op_log: std::collections::VecDeque<String>,
    pub show_op_log: bool,
    // Merge notifier
    pub merge_base_branch: String,
    pub merge_notifier_enabled: bool,
    pub merge_notifier_ahead: Option<i32>,
    pub merge_notifier_interval_secs: u64,
    pub merge_notifier_last_check: Option<std::time::Instant>,
    pub merge_base_picker: bool,
    pub merge_base_selected: usize,
    pub push_ff_only_enforce: bool,
    pub merge_base_candidates: Vec<String>,
    pub merge_notifier_log: std::collections::VecDeque<String>,
    pub show_merge_log: bool,
    // Prune merged confirmation
    pub prune_merged_pending: bool,
    // Remote prune confirmation
    pub remote_prune_pending: bool,
    // Pull/rebase toggles
    pub pull_ff_only: bool,
    pub pull_autostash: bool,
    pub pull_timeout_secs: u64,
    pub rebase_timeout_secs: u64,
    // Auto-fetch cadence
    pub auto_fetch_enabled: bool,
    pub auto_fetch_interval_secs: u64,
    pub auto_fetch_last_check: Option<std::time::Instant>,
    pub auto_fetch_remote: String,
    // PR helper
    pub pr_helper: bool,
    pub pr_list: Vec<PrItem>,
    pub pr_selected: usize,
    // Conflict filter
    pub conflicts_only: bool,
    pub conflicts_popup: bool,
    pub conflicts_popup_selected: usize,
    pub conflicts_guided: bool,
    pub conflicts_guided_selected: usize,
    // Interactive rebase UI
    pub rebase_todo: Vec<String>,
    pub rebase_todo_selected: usize,
    pub show_rebase_todo: bool,
    pub rebase_todo_dirty: bool,
    pub rebase_todo_original: Vec<String>,
    pub rebase_todo_path: Option<String>,
    pub rebase_todo_editing: bool,
    pub rebase_todo_edit_buffer: String,
    // Interactive rebase builder (new)
    pub rebase_editor_open: bool,
    pub rebase_entries: Vec<RebaseEntry>,
    pub rebase_cursor: usize,
    pub rebase_dirty: bool,
    pub rebase_target_only: bool,
    pub reword_message: Option<String>,
    pub reword_modal_open: bool,
    pub reword_focus_field: RewordField,
    pub reword_author_name: Option<String>,
    pub reword_author_email: Option<String>,
    // Edit operation fields (for when edit is stronger than reword)
    pub edit_message: Option<String>,
    pub edit_modal_open: bool,
    pub edit_focus_field: RewordField, // Reuse RewordField since fields are the same
    pub edit_author_name: Option<String>,
    pub edit_author_email: Option<String>,
    // Workflow assistant
    pub workflow_context: Option<crate::app::workflow::WorkflowContext>,
    // Custom commands from config
    pub custom_commands: std::collections::HashMap<String, String>,
}

// Main state object for the application
impl AppState {
    pub fn new() -> Self {
        Self {
            running: true,
            theme: ThemeConfig::default(),
            last_status: String::new(),
            status_summary: StatusSummary::default(),
            status_lines: Vec::new(),
            status_entries: Vec::new(),
            status_selected: 0,
            status_selected_path: String::new(),
            last_diff_path: String::new(),
            last_diff: String::new(),
            last_diff_truncated: false,
            last_diff_total: 0,
            last_diff_fetched_at: None,
            diff_mode: DiffMode::Working,
            diff_parsed: crate::git::DiffParseResult::default(),
            show_help: false,
            repo_path: ".".to_string(),
            last_status_error: None,
            error_guidance: None,
            focus: FocusPane::Status,
            key_help: vec![
                KeyHelp { key: "q / Ctrl+C", desc: "quit" },
                KeyHelp { key: ":", desc: "command palette" },
                KeyHelp { key: "h", desc: "toggle help" },
                KeyHelp { key: "r", desc: "refresh status" },
                KeyHelp { key: "j / k / ↑ / ↓", desc: "move selection" },
                KeyHelp { key: "Tab / Shift+Tab", desc: "cycle focus" },
                KeyHelp { key: "d", desc: "toggle diff mode (working/staged)" },
                KeyHelp { key: "[ / ]", desc: "scroll diff up/down" },
                KeyHelp { key: "< / >", desc: "scroll diff left/right" },
                KeyHelp { key: "+ / -", desc: "more/less context lines" },
                KeyHelp { key: "v", desc: "toggle side-by-side diff" },
                KeyHelp { key: "T", desc: "toggle tree/flat view" },
                KeyHelp { key: "W", desc: "toggle whitespace ignore" },
                KeyHelp { key: "D", desc: "toggle delta syntax highlight" },
                KeyHelp { key: "s", desc: "stage selected file(s)" },
                KeyHelp { key: "u", desc: "unstage selected file(s)" },
                KeyHelp { key: "S", desc: "stage all unstaged/untracked" },
                KeyHelp { key: "U", desc: "unstage all staged" },
                KeyHelp { key: "c", desc: "commit staged (palette)" },
                KeyHelp { key: "A", desc: "amend last commit (palette)" },
                KeyHelp { key: "P", desc: "push (palette)" },
                KeyHelp { key: "cp", desc: "cherry-pick commit (palette)" },
                KeyHelp { key: "rv", desc: "revert commit (palette)" },
                KeyHelp { key: "rc", desc: "rebase continue (palette)" },
                KeyHelp { key: "ra", desc: "rebase abort (palette)" },
                KeyHelp { key: "rs", desc: "reset soft HEAD~1 (palette)" },
                KeyHelp { key: "rm", desc: "reset mixed HEAD~1 (palette)" },
                KeyHelp { key: "rh", desc: "reset hard HEAD~1 (palette)" },
                KeyHelp { key: "Space", desc: "toggle multi-select" },
                KeyHelp { key: "n / N", desc: "jump next/prev staged file" },
                KeyHelp { key: "/", desc: "filter files" },
                KeyHelp { key: "Alt-[ / Alt-]", desc: "prev/next hunk" },
                KeyHelp { key: "H", desc: "stage selected hunk" },
                KeyHelp { key: "Ctrl+L", desc: "toggle line select mode" },
                KeyHelp { key: "Space (line mode)", desc: "toggle line selection" },
                KeyHelp { key: "Ctrl+S (line mode)", desc: "stage selected lines" },
                KeyHelp { key: "w", desc: "toggle word diff" },
                KeyHelp { key: "c", desc: "commit staged changes" },
                KeyHelp { key: "A", desc: "amend last commit" },
                KeyHelp { key: "x", desc: "discard file (with confirm)" },
                KeyHelp { key: "X", desc: "discard all (with confirm)" },
                KeyHelp { key: "Z", desc: "undo last commit (soft reset)" },
                KeyHelp { key: "b", desc: "show branches pane" },
                KeyHelp { key: "B", desc: "create new branch" },
                KeyHelp { key: "g", desc: "show tags pane" },
                KeyHelp { key: "l", desc: "show commit log pane" },
                KeyHelp { key: "L", desc: "file history for selected" },
                KeyHelp { key: "Ctrl+L", desc: "show reflog" },
                KeyHelp { key: "g (log)", desc: "toggle graph view" },
                KeyHelp { key: "Enter (log)", desc: "show commit detail" },
                KeyHelp { key: "C (log)", desc: "cherry-pick commit" },
                KeyHelp { key: "R (log)", desc: "revert commit" },
                KeyHelp { key: "z", desc: "show stash pane" },
                KeyHelp { key: "S", desc: "stash changes" },
                KeyHelp { key: "P", desc: "push to remote" },
                KeyHelp { key: "F", desc: "force push (with confirm)" },
                KeyHelp { key: "p", desc: "pull from remote" },
                KeyHelp { key: "Ctrl+P", desc: "pull with rebase" },
                KeyHelp { key: "f", desc: "fetch (with prune)" },
                KeyHelp { key: "Ctrl+F", desc: "fetch all remotes" },
                KeyHelp { key: "m (branches)", desc: "merge into current" },
                KeyHelp { key: "e (branches)", desc: "rebase onto branch" },
                KeyHelp { key: "o", desc: "open file in $EDITOR" },
                KeyHelp { key: "Esc", desc: "cancel / close modal" },
            ],
            last_refreshed: None,
            refreshing: false,
            last_refresh_time: None,
            help_selected: 0,
            detail_scroll: 0,
             detail_scroll_x: 0,
            current_branch: String::new(),
            selected_files: std::collections::HashSet::new(),
            branches: Vec::new(),
            branch_selected: 0,
            commits: Vec::new(),
            commit_selected: 0,
            commit_input: String::new(),
            commit_mode: false,
            amend_mode: false,
            amend_author_name: String::new(),
            amend_author_email: String::new(),
            last_commit_info: None,
            amend_editing_field: None,
            commit_template: None,
            feedback_message: None,
            status_filter: String::new(),
            filter_mode: false,
            file_scrolls: HashMap::new(),
            stashes: Vec::new(),
            stash_selected: 0,
            branch_create_mode: false,
            branch_name_input: String::new(),
            stash_create_mode: false,
            stash_message_input: String::new(),
            hunks: Vec::new(),
            hunk_selected: 0,
            word_diff: false,
            selected_lines: std::collections::HashSet::new(),
            line_select_mode: false,
            tags: Vec::new(),
            tag_selected: 0,
            has_delta: false,
            use_delta: false,
            diff_context: 3,
            ignore_whitespace: false,
            side_by_side: false,
            tree_view: false,
            reflog_entries: Vec::new(),
            reflog_selected: 0,
            commit_detail: None,
            file_history_path: None,
            log_filter: String::new(),
            log_filter_mode: false,
            log_graph: false,
            log_graph_text: String::new(),
            log_action_menu: false,
            log_action_selected: 0,
            log_action_commit_hash: None,
            confirm_action: None,
            confirm_message: None,
            remotes: Vec::new(),
            remote_selected: 0,
            command_palette: false,
            palette_input: String::new(),
            palette_selected: 0,
            log_selected_hashes: std::collections::HashSet::new(),
            rebase_base: None,
            async_tasks: Vec::new(),
            available_themes: Vec::new(),
            font_family: None,
            font_size: None,
            theme_picker: false,
            theme_picker_selected: 0,
            theme_preview_prior: None,
            load_full_diff: false,
            diff_focus: false,
            reset_pending: None,
            op_status: None,
            op_log: std::collections::VecDeque::new(),
            show_op_log: false,
            merge_base_branch: "development".to_string(),
            merge_notifier_enabled: false,
            merge_notifier_ahead: None,
            merge_notifier_interval_secs: 120,
            merge_notifier_last_check: None,
            merge_base_picker: false,
            merge_base_selected: 0,
            push_ff_only_enforce: true,
            merge_base_candidates: Vec::new(),
            merge_notifier_log: std::collections::VecDeque::new(),
            show_merge_log: false,
            prune_merged_pending: false,
            remote_prune_pending: false,
            pull_ff_only: true,
            pull_autostash: false,
            pull_timeout_secs: 30,
            rebase_timeout_secs: 30,
            auto_fetch_enabled: false,
            auto_fetch_interval_secs: 300,
            auto_fetch_last_check: None,
            auto_fetch_remote: "origin".to_string(),
            pr_helper: false,
            pr_list: Vec::new(),
            pr_selected: 0,
            conflicts_only: false,
            conflicts_popup: false,
            conflicts_popup_selected: 0,
            conflicts_guided: false,
            conflicts_guided_selected: 0,
            rebase_todo: Vec::new(),
            rebase_todo_selected: 0,
            show_rebase_todo: false,
            rebase_todo_dirty: false,
            rebase_todo_original: Vec::new(),
            rebase_todo_path: None,
            rebase_todo_editing: false,
            rebase_todo_edit_buffer: String::new(),
            rebase_editor_open: false,
            rebase_entries: Vec::new(),
            rebase_cursor: 0,
            rebase_dirty: false,
            rebase_target_only: false,
            reword_message: None,
            reword_modal_open: false,
            reword_focus_field: RewordField::Message,
            reword_author_name: None,
            reword_author_email: None,
            edit_message: None,
            edit_modal_open: false,
            edit_focus_field: RewordField::Message,
            edit_author_name: None,
            edit_author_email: None,
            workflow_context: None,
            custom_commands: std::collections::HashMap::new(),
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum FocusPane {
    Status,
    Branches,
    Log,
    Stash,
    Tags,
    Reflog,
}

#[derive(Debug, Clone)]
pub struct BranchEntry {
    pub name: String,
    pub is_remote: bool,
    pub ahead: Option<i32>,
    pub behind: Option<i32>,
}

#[derive(Debug, Clone)]
pub struct CommitEntry {
    pub hash: String,
    pub short_hash: String,
    pub message: String,
    pub author: String,
}

/// Information about the last commit (for amend operations)
#[derive(Debug, Clone)]
pub struct LastCommitInfo {
    pub author_name: String,
    pub author_email: String,
    pub message: String,
    pub date: String, // ISO format or relative
    #[allow(dead_code)]
    pub hash: String,
    pub short_hash: String,
}

/// Which field is being edited in amend mode
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AmendField {
    Message,
    AuthorName,
    AuthorEmail,
}

#[derive(Debug, Clone)]
pub struct StashEntry {
    pub name: String,
    pub message: String,
}

#[derive(Debug, Clone)]
pub struct TagEntry {
    pub name: String,
    pub message: String,
}

#[derive(Debug, Clone)]
pub struct ReflogEntry {
    pub short_hash: String,
    pub selector: String,
    pub action: String,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RewordField {
    Message,
    AuthorName,
    AuthorEmail,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RebaseAction {
    Pick,
    Reword,
    Edit,
    Squash,
    Fixup,
    Drop,
}

#[derive(Debug, Clone)]
pub struct RebaseEntry {
    pub hash: String,
    pub short_hash: String,
    pub message: String,
    pub action: RebaseAction,
}

/// Remote entry (future: remote management UI)
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct RemoteEntry {
    pub name: String,
    pub url: String,
}

/// Async task for background operations
#[derive(Debug, Clone)]
pub struct AsyncTask {
    pub id: u64,
    pub status: AsyncTaskStatus,
    pub started_at: std::time::Instant,
}

#[derive(Debug, Clone, PartialEq)]
pub enum AsyncTaskStatus {
    #[allow(dead_code)]
    Running,
    Completed,
    Failed(String),
}

#[derive(Debug, Clone)]
pub struct KeyHelp {
    pub key: &'static str,
    pub desc: &'static str,
}

#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct PrItem {
    pub number: String,
    pub title: String,
    pub _remote: String,
    pub _branch: String,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DiffMode {
    Working,
    Staged,
}