//! Git command implementations organized by functionality.
//!
//! This module contains all Git-related command implementations, split into
//! focused sub-modules for better organization and maintainability.
//!
//! **Module Organization:**
//! - `stage.rs` - Stage/unstage file operations
//! - `commit.rs` - Commit operations
//! - `push_pull.rs` - Push and pull operations
//! - `rebase.rs` - Rebase operations and todo management
//! - `cherry_pick_revert.rs` - Cherry-pick and revert operations
//! - `reset.rs` - Reset operations
//! - `branch_management.rs` - Branch listing and pruning
//! - `remote.rs` - Remote repository operations
//! - `pr.rs` - Pull request operations (GitHub-style)
//! - `log.rs` - Log viewing operations
//! - `editor.rs` - External editor integration
//! - `merge.rs` - Merge status checking
//! - `utils.rs` - Shared utility functions

pub mod stage;
pub mod commit;
pub mod push_pull;
pub mod rebase;
pub mod cherry_pick_revert;
pub mod reset;
pub mod branch_management;
pub mod remote;
pub mod pr;
pub mod log;
pub mod editor;
pub mod merge;
pub mod utils;

// Re-export all command types for convenience
pub use stage::{StageFilesCommand, UnstageFilesCommand};
pub use commit::CommitCommand;
pub use push_pull::{PushCommand, PullCommand, PullRebaseCommand};
pub use rebase::{
    RebaseContinueCommand,
    RebaseAbortCommand,
    RebaseSkipCommand,
    RebaseTodoSaveCommand,
    RebaseTodoLoadCommand,
    RebaseTodoOpenCommand,
};
pub use cherry_pick_revert::{CherryPickCommand, RevertCommand};
pub use reset::ResetCommand;
pub use branch_management::{ListMergedBranchesCommand, PruneMergedBranchesCommand};
pub use remote::{
    RemotePruneCommand,
    ShowRemoteUrlCommand,
    SetRemoteSshCommand,
    AutoFetchCommand,
};
pub use pr::{PrListCommand, PrCheckoutCommand, PrOpenCommand};
pub use log::{LogBriefCommand, LogStatsCommand};
pub use editor::OpenInEditorCommand;
pub use merge::CheckMergeStatusCommand;

// Re-export utility functions (used internally by commands)
pub(crate) use utils::to_github_pr_url;

#[cfg(test)]
mod tests {
    use super::*;
    use crate::app::AppState;
    use crate::commands::Command;
    use crate::services::GitService;
    use std::fs;

    #[test]
    fn to_github_pr_url_https() {
        let url = "https://github.com/org/repo.git";
        let ssh = to_github_pr_url(url, "12").unwrap();
        assert_eq!(ssh, "https://github.com/org/repo/pull/12");
    }

    #[test]
    fn rebase_todo_save_writes_file_and_clears_dirty() {
        let dir = std::env::temp_dir().join("eazygit_rebase_todo_save");
        let _ = fs::create_dir_all(&dir);
        let path = dir.join("git-rebase-todo");

        let mut state = AppState::new();
        state.rebase_todo = vec!["pick a".into()];
        state.rebase_todo_path = Some(path.to_string_lossy().to_string());
        state.rebase_todo_dirty = true;

        let cmd = RebaseTodoSaveCommand;
        let result = cmd.execute(&GitService::new(), &state).unwrap();

        if let crate::commands::CommandResult::StateUpdate(ns) = result {
            let content = fs::read_to_string(&path).unwrap();
            assert!(content.starts_with("pick a"));
            assert!(!ns.rebase_todo_dirty);
            assert!(ns.feedback_message.is_some());
        } else {
            panic!("unexpected command result");
        }
    }

    #[test]
    fn rebase_todo_save_validates_actions() {
        let dir = std::env::temp_dir().join("eazygit_rebase_todo_save_invalid");
        let _ = fs::create_dir_all(&dir);
        let path = dir.join("git-rebase-todo");
        let mut state = AppState::new();
        state.rebase_todo = vec!["# comment only".into()];
        state.rebase_todo_path = Some(path.to_string_lossy().to_string());

        let cmd = RebaseTodoSaveCommand;
        let result = cmd.execute(&GitService::new(), &state).unwrap();

        if let crate::commands::CommandResult::StateUpdate(ns) = result {
            assert!(ns.last_status_error.is_some());
        } else {
            panic!("unexpected command result");
        }
    }
}

