//! Worktree workflow implementations.
//!
//! - **follow**: Hard-reset a work branch to track a target branch (e.g. main)
//! - **take**: Squash-merge changes from a worktree branch into a target branch

use crate::error::{ProjectError, Result};
use crate::git::runner::GitRunner;

/// Follow workflow: hard-reset work_branch to match target_branch.
///
/// This is used when a worktree's work branch needs to catch up with
/// the main branch. After this operation, work_branch HEAD will be
/// identical to target_branch HEAD.
///
/// **Destructive**: Discards any uncommitted changes on work_branch.
pub async fn follow(runner: &GitRunner, work_branch: &str, target_branch: &str) -> Result<()> {
    // Ensure we're on the work branch
    let current = runner.current_branch().await?;
    if current != work_branch {
        runner.checkout(work_branch).await?;
    }

    runner.reset_hard(target_branch).await?;
    Ok(())
}

/// Take workflow: squash-merge changes from source_branch into target_branch.
///
/// This brings all the work from source_branch into target_branch as a
/// single commit. If `auto_commit` is true, the squash is committed
/// automatically with a generated message.
///
/// Returns the commit hash if auto_commit is true, None otherwise
/// (leaving the changes staged for manual commit).
pub async fn take(
    runner: &GitRunner,
    source_branch: &str,
    target_branch: &str,
    auto_commit: bool,
) -> Result<Option<String>> {
    // Switch to target branch
    let current = runner.current_branch().await?;
    if current != target_branch {
        runner.checkout(target_branch).await?;
    }

    // Squash-merge
    runner.merge_squash(source_branch).await.map_err(|e| {
        ProjectError::Validation(format!(
            "squash-merge from '{}' into '{}' failed: {}",
            source_branch, target_branch, e
        ))
    })?;

    if auto_commit {
        let message = format!("Squash merge from {}", source_branch);
        let hash = runner.commit(&message).await?;
        Ok(Some(hash))
    } else {
        Ok(None)
    }
}
