//! Log commands.
//!
//! Handles Git log operations including brief and stats views.

use crate::commands::{Command, CommandResult};
use crate::services::GitService;
use crate::app::{AppState, Action, reducer};
use crate::errors::CommandError;
use tracing::instrument;

/// Log brief
pub struct LogBriefCommand {
    pub limit: usize,
}

impl Command for LogBriefCommand {
    #[instrument(skip(self, git, state), fields(limit = self.limit))]
    fn execute(
        &self,
        git: &GitService,
        state: &AppState,
    ) -> Result<CommandResult, CommandError> {
        let mut new_state = state.clone();
        new_state = reducer(new_state, Action::SetOpStatus(Some("log brief…".into())));
        match git.log_brief(&state.repo_path, self.limit) {
            Ok(out) => {
                for line in out.lines() {
                    new_state = reducer(new_state, Action::AppendOpLog(line.to_string()));
                }
                new_state = reducer(new_state, Action::ShowOpLog); // Automatically open op log viewer
                new_state = reducer(new_state, Action::SetFeedback(Some("Log brief ready".into())));
            }
            Err(e) => {
                new_state = reducer(new_state, Action::AppendOpLog(format!("log brief error: {e}")));
                new_state = reducer(new_state, Action::SetStatusError(Some(format!("log brief error: {e}"))));
            }
        }
        new_state = reducer(new_state, Action::SetOpStatus(None));
        Ok(CommandResult::StateUpdate(new_state))
    }
}

/// Log stats
pub struct LogStatsCommand {
    pub limit: usize,
}

impl Command for LogStatsCommand {
    #[instrument(skip(self, git, state), fields(limit = self.limit))]
    fn execute(
        &self,
        git: &GitService,
        state: &AppState,
    ) -> Result<CommandResult, CommandError> {
        let mut new_state = state.clone();
        new_state = reducer(new_state, Action::SetOpStatus(Some("log stats…".into())));
        match git.log_stats(&state.repo_path, self.limit) {
            Ok(out) => {
                for line in out.lines() {
                    new_state = reducer(new_state, Action::AppendOpLog(line.to_string()));
                }
                new_state = reducer(new_state, Action::ShowOpLog); // Automatically open op log viewer
                new_state = reducer(new_state, Action::SetFeedback(Some("Log stats ready".into())));
            }
            Err(e) => {
                new_state = reducer(new_state, Action::AppendOpLog(format!("log stats error: {e}")));
                new_state = reducer(new_state, Action::SetStatusError(Some(format!("log stats error: {e}"))));
            }
        }
        new_state = reducer(new_state, Action::SetOpStatus(None));
        Ok(CommandResult::StateUpdate(new_state))
    }
}

