use crate::app::{Action, AppState};
use std::path::PathBuf;

/// Current workflow state
#[derive(Debug, Clone, PartialEq)]
pub enum WorkflowState {
    Clean,
    Conflicts,
    RebaseInProgress,
    MergeInProgress,
    CherryPickInProgress,
    RevertInProgress,
    Staging,
    Committing,
}

/// Workflow context with state and suggestions
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct WorkflowContext {
    pub state: WorkflowState,
    pub message: String,
    pub next_steps: Vec<WorkflowStep>,
    pub progress: Option<WorkflowProgress>,
}

/// A suggested next step in the workflow
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct WorkflowStep {
    pub key: String,
    pub label: String,
    pub action: Option<Action>,
    pub description: String,
}

/// Progress information for multi-step workflows
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct WorkflowProgress {
    pub current: usize,
    pub total: usize,
    pub step_name: String,
}

impl WorkflowContext {
    /// Detect current workflow state from AppState
    pub fn detect(state: &AppState) -> Self {
        let repo_path = PathBuf::from(&state.repo_path);
        
        // Check for rebase in progress
        if repo_path.join(".git/rebase-merge").exists() 
            || repo_path.join(".git/rebase-apply").exists() {
            return Self::rebase_context(state);
        }
        
        // Check for merge in progress
        if repo_path.join(".git/MERGE_HEAD").exists() {
            return Self::merge_context(state);
        }
        
        // Check for cherry-pick in progress
        if repo_path.join(".git/CHERRY_PICK_HEAD").exists() {
            return Self::cherry_pick_context(state);
        }
        
        // Check for revert in progress
        if repo_path.join(".git/REVERT_HEAD").exists() {
            return Self::revert_context(state);
        }
        
        // Check for conflicts
        let has_conflicts = state.status_entries.iter().any(|e| e.conflict);
        if has_conflicts {
            return Self::conflicts_context(state);
        }
        
        // Check if committing
        if state.commit_mode {
            return Self::committing_context(state);
        }
        
        // Check if staging
        let has_staged = state.status_entries.iter().any(|e| e.staged);
        let has_unstaged = state.status_entries.iter().any(|e| e.unstaged);
        if has_staged || has_unstaged {
            return Self::staging_context(state);
        }
        
        // Default: clean state
        Self::clean_context(state)
    }
    
    fn rebase_context(state: &AppState) -> Self {
        let progress = if !state.rebase_todo.is_empty() {
            let current = state.rebase_todo_selected.min(state.rebase_todo.len());
            Some(WorkflowProgress {
                current,
                total: state.rebase_todo.len(),
                step_name: "rebase".to_string(),
            })
        } else {
            None
        };
        
        Self {
            state: WorkflowState::RebaseInProgress,
            message: "Rebase in progress".to_string(),
            next_steps: vec![
                WorkflowStep {
                    key: "rc".to_string(),
                    label: "Continue rebase".to_string(),
                    action: Some(Action::RebaseContinue),
                    description: "Apply the current commit and continue".to_string(),
                },
                WorkflowStep {
                    key: "ra".to_string(),
                    label: "Abort rebase".to_string(),
                    action: Some(Action::RebaseAbort),
                    description: "Cancel the rebase and return to original state".to_string(),
                },
                WorkflowStep {
                    key: "rs".to_string(),
                    label: "Skip commit".to_string(),
                    action: Some(Action::RebaseSkip),
                    description: "Skip the current commit".to_string(),
                },
                WorkflowStep {
                    key: "rt".to_string(),
                    label: "Edit rebase todo".to_string(),
                    action: Some(Action::ShowRebaseTodo),
                    description: "Edit the rebase todo list".to_string(),
                },
            ],
            progress,
        }
    }
    
    fn merge_context(state: &AppState) -> Self {
        let has_conflicts = state.status_entries.iter().any(|e| e.conflict);
        
        if has_conflicts {
            Self {
                state: WorkflowState::MergeInProgress,
                message: "Merge in progress - conflicts detected".to_string(),
                next_steps: vec![
                    WorkflowStep {
                        key: "g".to_string(),
                        label: "Open guided resolution".to_string(),
                        action: Some(Action::ShowConflictsGuided),
                        description: "Get step-by-step help resolving conflicts".to_string(),
                    },
                    WorkflowStep {
                        key: "o".to_string(),
                        label: "Open conflicts in editor".to_string(),
                        action: None,
                        description: "Edit conflict files manually".to_string(),
                    },
                ],
                progress: None,
            }
        } else {
            Self {
                state: WorkflowState::MergeInProgress,
                message: "Merge in progress - ready to commit".to_string(),
                next_steps: vec![
                    WorkflowStep {
                        key: "c".to_string(),
                        label: "Commit merge".to_string(),
                        action: Some(Action::StartCommit),
                        description: "Complete the merge by committing".to_string(),
                    },
                ],
                progress: None,
            }
        }
    }
    
    fn cherry_pick_context(state: &AppState) -> Self {
        let has_conflicts = state.status_entries.iter().any(|e| e.conflict);
        
        if has_conflicts {
            Self {
                state: WorkflowState::CherryPickInProgress,
                message: "Cherry-pick in progress - conflicts detected".to_string(),
                next_steps: vec![
                    WorkflowStep {
                        key: "g".to_string(),
                        label: "Open guided resolution".to_string(),
                        action: Some(Action::ShowConflictsGuided),
                        description: "Get step-by-step help resolving conflicts".to_string(),
                    },
                    WorkflowStep {
                        key: "c".to_string(),
                        label: "Commit after resolving".to_string(),
                        action: Some(Action::StartCommit),
                        description: "Complete the cherry-pick after resolving conflicts".to_string(),
                    },
                ],
                progress: None,
            }
        } else {
            Self {
                state: WorkflowState::CherryPickInProgress,
                message: "Cherry-pick in progress - ready to commit".to_string(),
                next_steps: vec![
                    WorkflowStep {
                        key: "c".to_string(),
                        label: "Commit cherry-pick".to_string(),
                        action: Some(Action::StartCommit),
                        description: "Complete the cherry-pick".to_string(),
                    },
                ],
                progress: None,
            }
        }
    }
    
    fn revert_context(_state: &AppState) -> Self {
        Self {
            state: WorkflowState::RevertInProgress,
            message: "Revert in progress".to_string(),
            next_steps: vec![
                WorkflowStep {
                    key: "c".to_string(),
                    label: "Commit revert".to_string(),
                    action: Some(Action::StartCommit),
                    description: "Complete the revert".to_string(),
                },
            ],
            progress: None,
        }
    }
    
    fn conflicts_context(state: &AppState) -> Self {
        let conflict_count = state.status_entries.iter().filter(|e| e.conflict).count();
        
        Self {
            state: WorkflowState::Conflicts,
            message: format!("{} conflict(s) detected", conflict_count),
            next_steps: vec![
                WorkflowStep {
                    key: "g".to_string(),
                    label: "Open guided resolution".to_string(),
                    action: Some(Action::ShowConflictsGuided),
                    description: "Get step-by-step help resolving conflicts".to_string(),
                },
                WorkflowStep {
                    key: "n".to_string(),
                    label: "Next conflict".to_string(),
                    action: Some(Action::StatusNextConflict),
                    description: "Navigate to next conflict".to_string(),
                },
                WorkflowStep {
                    key: "p".to_string(),
                    label: "Previous conflict".to_string(),
                    action: Some(Action::StatusPrevConflict),
                    description: "Navigate to previous conflict".to_string(),
                },
            ],
            progress: None,
        }
    }
    
    fn committing_context(_state: &AppState) -> Self {
        Self {
            state: WorkflowState::Committing,
            message: "Entering commit message".to_string(),
            next_steps: vec![
                WorkflowStep {
                    key: "Enter".to_string(),
                    label: "Commit".to_string(),
                    action: Some(Action::CommitSubmit),
                    description: "Commit with the entered message".to_string(),
                },
                WorkflowStep {
                    key: "Esc".to_string(),
                    label: "Cancel".to_string(),
                    action: Some(Action::CancelCommit),
                    description: "Cancel commit and return".to_string(),
                },
            ],
            progress: None,
        }
    }
    
    fn staging_context(state: &AppState) -> Self {
        let staged_count = state.status_entries.iter().filter(|e| e.staged).count();
        let unstaged_count = state.status_entries.iter().filter(|e| e.unstaged).count();
        
        let message = if staged_count > 0 && unstaged_count > 0 {
            format!("{} staged, {} unstaged changes", staged_count, unstaged_count)
        } else if staged_count > 0 {
            format!("{} staged change(s) ready to commit", staged_count)
        } else {
            format!("{} unstaged change(s)", unstaged_count)
        };
        
        let mut steps = vec![];
        
        if unstaged_count > 0 {
            steps.push(WorkflowStep {
                key: "s".to_string(),
                label: "Stage selected".to_string(),
                action: Some(Action::StageSelectedFile),
                description: "Stage the selected file".to_string(),
            });
            steps.push(WorkflowStep {
                key: "S".to_string(),
                label: "Stage all".to_string(),
                action: Some(Action::StageAllFiles),
                description: "Stage all unstaged files".to_string(),
            });
        }
        
        if staged_count > 0 {
            steps.push(WorkflowStep {
                key: "c".to_string(),
                label: "Commit".to_string(),
                action: Some(Action::StartCommit),
                description: "Commit staged changes".to_string(),
            });
        }
        
        Self {
            state: WorkflowState::Staging,
            message,
            next_steps: steps,
            progress: None,
        }
    }
    
    fn clean_context(_state: &AppState) -> Self {
        Self {
            state: WorkflowState::Clean,
            message: "Working directory clean".to_string(),
            next_steps: vec![
                WorkflowStep {
                    key: "b".to_string(),
                    label: "View branches".to_string(),
                    action: Some(Action::FocusNext),
                    description: "Switch branches or create new ones".to_string(),
                },
                WorkflowStep {
                    key: "l".to_string(),
                    label: "View log".to_string(),
                    action: Some(Action::FocusNext),
                    description: "Browse commit history".to_string(),
                },
                WorkflowStep {
                    key: "P".to_string(),
                    label: "Push".to_string(),
                    action: Some(Action::Push),
                    description: "Push commits to remote".to_string(),
                },
            ],
            progress: None,
        }
    }
    
    /// Format workflow context for display
    #[allow(dead_code)]
    pub fn format_display(&self) -> String {
        let mut lines = vec![self.message.clone()];
        
        if let Some(ref progress) = self.progress {
            lines.push(format!("Progress: {}/{} - {}", progress.current, progress.total, progress.step_name));
        }
        
        if !self.next_steps.is_empty() {
            lines.push(String::new());
            lines.push("Next steps:".to_string());
            for step in &self.next_steps {
                lines.push(format!("  [{}] {} - {}", step.key, step.label, step.description));
            }
        }
        
        lines.join("\n")
    }
}

