//! Policy operation handlers (ack, bless, update, baseline, diff, status, init)

use std::process::ExitCode;

use aphoria::{AcknowledgeArgs, AphoriaConfig, BlessArgs, UpdateArgs};

use crate::cli::AckCommands;

/// Handle the ack command and its subcommands.
pub async fn handle_ack_command(command: AckCommands, config: &AphoriaConfig) -> ExitCode {
    match command {
        AckCommands::Add { concept_path, reason, expires } => {
            handle_ack_add(concept_path, reason, expires, config).await
        }
        AckCommands::Export { output } => handle_ack_export(output, config).await,
        AckCommands::Import { input } => handle_ack_import(input, config).await,
    }
}

async fn handle_ack_add(
    concept_path: String,
    reason: String,
    expires: Option<String>,
    config: &AphoriaConfig,
) -> ExitCode {
    let args = AcknowledgeArgs { concept_path, reason, expires: expires.clone() };

    match aphoria::acknowledge(args, config).await {
        Ok(()) => {
            if let Some(exp) = expires {
                println!("Conflict acknowledged (expires {exp}).");
            } else {
                println!("Conflict acknowledged.");
            }
            ExitCode::SUCCESS
        }
        Err(e) => {
            eprintln!("Acknowledge error: {e}");
            ExitCode::from(3)
        }
    }
}

async fn handle_ack_export(output: Option<std::path::PathBuf>, config: &AphoriaConfig) -> ExitCode {
    match aphoria::export_acks(output, config).await {
        Ok(stats) => {
            println!(
                "Exported {} acknowledgments to {}",
                stats.exported,
                stats.output_path.display()
            );
            ExitCode::SUCCESS
        }
        Err(e) => {
            eprintln!("Export error: {e}");
            ExitCode::from(3)
        }
    }
}

async fn handle_ack_import(input: Option<std::path::PathBuf>, config: &AphoriaConfig) -> ExitCode {
    match aphoria::import_acks(input, config).await {
        Ok(stats) => {
            println!(
                "Imported {} acknowledgments ({} skipped as duplicates)",
                stats.imported, stats.skipped
            );
            ExitCode::SUCCESS
        }
        Err(e) => {
            eprintln!("Import error: {e}");
            ExitCode::from(3)
        }
    }
}

pub async fn handle_bless(
    concept_path: String,
    predicate: String,
    value: String,
    reason: String,
    config: &AphoriaConfig,
) -> ExitCode {
    let args = BlessArgs { concept_path, predicate, value, reason };

    match aphoria::bless(args, config).await {
        Ok(()) => {
            println!("Pattern blessed as authoritative standard.");
            ExitCode::SUCCESS
        }
        Err(e) => {
            eprintln!("Bless error: {e}");
            ExitCode::from(3)
        }
    }
}

pub async fn handle_update(
    concept_path: String,
    value: String,
    reason: String,
    config: &AphoriaConfig,
) -> ExitCode {
    let args = UpdateArgs { concept_path, value, reason };

    match aphoria::update(args, config).await {
        Ok(()) => {
            println!("Policy update recorded.");
            ExitCode::SUCCESS
        }
        Err(e) => {
            eprintln!("Update error: {e}");
            ExitCode::from(3)
        }
    }
}

pub async fn handle_baseline(config: &AphoriaConfig) -> ExitCode {
    match aphoria::set_baseline(config).await {
        Ok(()) => {
            println!("Baseline set.");
            ExitCode::SUCCESS
        }
        Err(e) => {
            eprintln!("Baseline error: {e}");
            ExitCode::from(3)
        }
    }
}

pub async fn handle_diff(config: &AphoriaConfig) -> ExitCode {
    match aphoria::show_diff(config).await {
        Ok(output) => {
            println!("{output}");
            ExitCode::SUCCESS
        }
        Err(e) => {
            eprintln!("Diff error: {e}");
            ExitCode::from(3)
        }
    }
}

pub async fn handle_status(config: &AphoriaConfig) -> ExitCode {
    match aphoria::show_status(config).await {
        Ok(output) => {
            println!("{output}");
            ExitCode::SUCCESS
        }
        Err(e) => {
            eprintln!("Status error: {e}");
            ExitCode::from(3)
        }
    }
}

pub async fn handle_init(config: &AphoriaConfig) -> ExitCode {
    match aphoria::initialize(config).await {
        Ok(()) => {
            println!("Aphoria initialized. Run `aphoria scan <project>` to begin.");
            ExitCode::SUCCESS
        }
        Err(e) => {
            eprintln!("Init error: {e}");
            ExitCode::from(3)
        }
    }
}
