use anyhow::Result;
use tempfile::TempDir;

use workgraph::graph::parse_delay;

#[test]
fn test_verify_timeout_parsing() -> Result<()> {
    // Test valid duration parsing
    assert_eq!(parse_delay("30s"), Some(30));
    assert_eq!(parse_delay("5m"), Some(300));
    assert_eq!(parse_delay("2h"), Some(7200));
    assert_eq!(parse_delay("1d"), Some(86400));

    // Test invalid duration parsing
    assert_eq!(parse_delay("invalid"), None);
    assert_eq!(parse_delay(""), None);
    assert_eq!(parse_delay("30x"), None);

    Ok(())
}

#[test]
fn test_verify_timeout_cli_basic() -> Result<()> {
    // Test the CLI --verify-timeout flag basic functionality
    let temp_dir = TempDir::new()?;
    let project_root = temp_dir.path();

    // Initialize a WG project
    let init_output = std::process::Command::new("wg")
        .args(&["init", "--route", "claude-cli"])
        .current_dir(project_root)
        .output()?;

    if !init_output.status.success() {
        eprintln!(
            "Init failed: {}",
            String::from_utf8_lossy(&init_output.stderr)
        );
        return Ok(()); // Skip test if can't initialize
    }

    // Create a task with verify timeout using CLI
    let output = std::process::Command::new("wg")
        .args(&["add", "Test CLI verify timeout", "--verify-timeout", "999s"])
        .current_dir(project_root)
        .output()?;

    // Should succeed (CLI should accept the flag without error)
    if !output.status.success() {
        let stderr = String::from_utf8_lossy(&output.stderr);
        // Only fail if it's specifically a timeout parsing error
        if stderr.contains("verify-timeout") || stderr.contains("invalid duration") {
            anyhow::bail!("CLI verify-timeout flag failed: {}", stderr);
        }
        // Otherwise skip test
        return Ok(());
    }

    // Check that task was created successfully
    let list_output = std::process::Command::new("wg")
        .args(&["list"])
        .current_dir(project_root)
        .output()?;

    if list_output.status.success() {
        let list_text = String::from_utf8_lossy(&list_output.stdout);
        assert!(list_text.contains("Test CLI verify timeout"));
    }

    Ok(())
}

#[test]
fn test_verify_timeout_duration_formats() -> Result<()> {
    // Test different duration formats through CLI
    let temp_dir = TempDir::new()?;
    let project_root = temp_dir.path();

    let init_output = std::process::Command::new("wg")
        .args(&["init", "--route", "claude-cli"])
        .current_dir(project_root)
        .output()?;

    if !init_output.status.success() {
        return Ok(()); // Skip if can't initialize
    }

    // Test different duration formats
    let test_cases = vec!["30s", "5m", "2h", "1d"];

    for timeout in test_cases {
        let title = format!("Test timeout {}", timeout);

        let output = std::process::Command::new("wg")
            .args(&["add", &title, "--verify-timeout", timeout])
            .current_dir(project_root)
            .output()?;

        // Should not fail with parse error
        if !output.status.success() {
            let stderr = String::from_utf8_lossy(&output.stderr);
            if stderr.contains("invalid duration") || stderr.contains("parse") {
                panic!("Failed to parse valid duration format: {}", timeout);
            }
        }
    }

    Ok(())
}

#[test]
fn test_verify_timeout_duration_conversion() -> Result<()> {
    // Test various time unit conversions
    assert_eq!(parse_delay("0s"), Some(0));
    assert_eq!(parse_delay("1s"), Some(1));
    assert_eq!(parse_delay("60s"), Some(60));
    assert_eq!(parse_delay("1m"), Some(60));
    assert_eq!(parse_delay("90m"), Some(5400));
    assert_eq!(parse_delay("1h"), Some(3600));
    assert_eq!(parse_delay("24h"), Some(86400));
    assert_eq!(parse_delay("1d"), Some(86400));
    assert_eq!(parse_delay("7d"), Some(604800));

    Ok(())
}

#[test]
fn test_verify_timeout_edge_cases() -> Result<()> {
    // Test edge cases in duration parsing
    assert_eq!(parse_delay("0s"), Some(0));
    assert_eq!(parse_delay("1s"), Some(1));

    // Test whitespace handling
    assert_eq!(parse_delay(" 30s "), Some(30));
    assert_eq!(parse_delay("5m "), Some(300));

    // Test invalid formats
    assert_eq!(parse_delay("30"), None); // No unit
    assert_eq!(parse_delay("s"), None); // No number
    assert_eq!(parse_delay("abc"), None); // Invalid number
    assert_eq!(parse_delay("30x"), None); // Invalid unit

    Ok(())
}
