// Test utilities for component testing

use crate::components::Component;
use crate::app::AppState;
use crate::services::GitService;
use std::sync::Arc;

/// Create a mock GitService for testing
pub fn create_mock_git_service() -> Arc<GitService> {
    Arc::new(GitService::new())
}

/// Create a minimal AppState for testing
pub fn create_test_state() -> AppState {
    let mut state = AppState::new();
    state.repo_path = "/tmp/test-repo".to_string();
    state
}

/// Helper to test component event handling
pub fn test_component_event<T: Component>(
    component: &mut T,
    event: crate::input::InputEvent,
    state: &AppState,
) -> Result<Option<crate::app::Action>, crate::errors::ComponentError> {
    component.handle_event(event, state)
}

/// Helper to test component update
#[allow(dead_code)]
pub fn test_component_update<T: Component>(
    component: &mut T,
    action: crate::app::Action,
    state: &mut AppState,
) -> Result<(), crate::errors::ComponentError> {
    component.update(action, state)
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::components::{StatusPane, BranchesPane, LogPane};
    use crate::input::InputEvent;
    use crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers};

    #[test]
    fn test_status_pane_creation() {
        let git_service = create_mock_git_service();
        let pane = StatusPane::new(git_service);
        assert_eq!(pane.name(), "StatusPane");
    }

    #[test]
    fn test_branches_pane_creation() {
        let git_service = create_mock_git_service();
        let pane = BranchesPane::new(git_service);
        assert_eq!(pane.name(), "BranchesPane");
    }

    #[test]
    fn test_status_pane_handles_key_events() {
        let git_service = create_mock_git_service();
        let mut pane = StatusPane::new(git_service);
        let state = create_test_state();
        
        let key_event = InputEvent::Key(KeyEvent {
            code: KeyCode::Char('j'),
            modifiers: KeyModifiers::empty(),
            kind: KeyEventKind::Press,
            state: crossterm::event::KeyEventState::empty(),
        });
        
        let result = test_component_event(&mut pane, key_event, &state);
        assert!(result.is_ok());
    }

    #[test]
    fn test_branches_pane_handles_navigation() {
        let git_service = create_mock_git_service();
        let mut pane = BranchesPane::new(git_service);
        let state = create_test_state();
        
        let key_event = InputEvent::Key(KeyEvent {
            code: KeyCode::Char('k'),
            modifiers: KeyModifiers::empty(),
            kind: KeyEventKind::Press,
            state: crossterm::event::KeyEventState::empty(),
        });
        
        let result = test_component_event(&mut pane, key_event, &state);
        assert!(result.is_ok());
    }

    #[test]
    fn test_log_pane_creation_and_event() {
        let git_service = create_mock_git_service();
        let mut pane = LogPane::new(git_service);
        let mut state = create_test_state();
        state.commits = vec![crate::app::state::CommitEntry {
            hash: "abc".to_string(),
            short_hash: "abc".to_string(),
            message: "msg".to_string(),
            author: "me".to_string(),
        }];
        let key_event = InputEvent::Key(KeyEvent {
            code: KeyCode::Char('j'),
            modifiers: KeyModifiers::empty(),
            kind: KeyEventKind::Press,
            state: crossterm::event::KeyEventState::empty(),
        });
        let result = test_component_event(&mut pane, key_event, &state);
        assert!(result.is_ok());
    }
}
