use anyhow::Result;

use crate::error::PawlError;
use crate::model::event::event_timestamp;
use crate::model::{Event, TaskStatus};

use super::common::Project;
use super::start;
use super::start::{resume_workflow, StepRecord};

/// Mark current step as done (approve waiting step, or complete in_viewport step)
pub fn done(task_name: &str, message: Option<&str>) -> Result<()> {
    let project = Project::load()?;
    let task_name = project.resolve_task_name(task_name)?;

    project.detect_viewport_loss(&task_name)?;

    let state = project.replay_task(&task_name)?;
    let Some(state) = state else {
        return Err(PawlError::StateConflict {
            task: task_name.clone(),
            status: "pending".into(),
            message: format!("not started. Use 'pawl start {}' to begin", task_name),
        }.into());
    };

    let step_idx = state.current_step;

    match state.status {
        TaskStatus::Running => {
            // Agent in viewport reporting done — go through unified pipeline
            let (_, config) = project.workflow_for(&task_name)?;
            let step = &config.workflow[step_idx];

            let record = StepRecord {
                exit_code: 0,
                duration: None,
                stdout: message.map(|s| s.to_string()),
                stderr: None,
            };

            eprintln!("Step {} marked as done.", step_idx + 1);

            // Unified pipeline: combine → decide → split
            let should_continue = start::settle_step(
                &project, &task_name, step_idx, step, record
            )?;

            // Cleanup viewport — but not if retrying (must happen before resume_workflow
            // which may open a new viewport for the next step with the same name)
            let new_state = project.replay_task(&task_name)?;
            let retrying = matches!(&new_state,
                Some(s) if s.status == TaskStatus::Running && s.current_step == step_idx
            );
            if !retrying {
                if let Ok(vp) = project.viewport_for(&task_name) {
                    let _ = vp.close(&task_name);
                }
            }

            if should_continue {
                resume_workflow(&project, &task_name)?;
            }
        }
        TaskStatus::Waiting => {
            // Manual approval: emit StepResumed and continue
            project.append_event(&task_name, &Event::StepResumed {
                ts: event_timestamp(),
                step: step_idx,
                message: message.map(|s| s.to_string()),
            })?;

            eprintln!("Step {} approved.", step_idx + 1);
            resume_workflow(&project, &task_name)?;
        }
        _ => {
            return Err(PawlError::StateConflict {
                task: task_name.clone(),
                status: state.status.to_string(),
                message: "cannot mark as done".into(),
            }.into());
        }
    }

    // Output final state as JSON
    project.output_task_state(&task_name)?;

    Ok(())
}
