// Tracing integration demo
// Run with: cargo run --example tracing_demo --features tracing
//
// This example shows how with_tracing() automatically logs error responses
// at the appropriate level (WARN for 4xx, ERROR for 5xx).

#![cfg(feature = "tracing")]

use anycms_core::{ApiResult, ApiResultTracing};
use serde::Serialize;

#[derive(Debug, Serialize)]
struct User {
    id: u32,
    name: String,
}

fn main() {
    // Initialize tracing subscriber so we can see the output
    tracing_subscriber::fmt()
        .with_target(false)
        .with_thread_ids(false)
        .init();

    println!("=== anycms-core tracing demo ===");
    println!();

    // 1. Success response — no log emitted
    println!("1. Success response (no log emitted):");
    let user = User {
        id: 1,
        name: "Alice".to_string(),
    };
    let result = ApiResult::value(user).with_tracing();
    println!("   success = {}, code = {:?}", result.success, result.code);
    println!();

    // 2. Client error (4xx) — logged at WARN level
    println!("2. Client error (4xx) — logged at WARN:");
    let result: ApiResult<User> = ApiResult::fail("Invalid request parameters")
        .with_code(400)
        .with_tracing();
    println!("   success = {}, code = {:?}", result.success, result.code);
    println!();

    // 3. Not found (404) — logged at WARN level
    println!("3. Not found (404) — logged at WARN:");
    let result: ApiResult<User> = ApiResult::fail("User not found")
        .with_code(404)
        .with_tracing();
    println!("   success = {}, code = {:?}", result.success, result.code);
    println!();

    // 4. Validation error (422) — logged at WARN level
    println!("4. Validation error (422) — logged at WARN:");
    let result: ApiResult<User> = ApiResult::fail("Validation failed")
        .with_code(422)
        .with_biz_code(10001)
        .with_tracing();
    println!(
        "   success = {}, code = {:?}, biz_code = {:?}",
        result.success, result.code, result.biz_code
    );
    println!();

    // 5. Server error (5xx) — logged at ERROR level
    println!("5. Server error (500) — logged at ERROR:");
    let result: ApiResult<User> = ApiResult::fail("Database connection timeout")
        .with_code(500)
        .with_tracing();
    println!("   success = {}, code = {:?}", result.success, result.code);
    println!();

    // 6. Server error with trace_id — logged at ERROR with trace_id field
    println!("6. Server error with trace_id — logged at ERROR:");
    let result: ApiResult<User> = ApiResult::fail("Internal processing error")
        .with_code(500)
        .with_trace_id("req-abc-123-def")
        .with_tracing();
    println!(
        "   success = {}, code = {:?}, trace_id = {:?}",
        result.success, result.code, result.trace_id
    );
    println!();

    // 7. Using ApiResult::fail().with_code() for typed error construction
    println!("7. Using ApiResult::fail().with_code() — logged at WARN:");
    let result: ApiResult<User> = ApiResult::fail("Resource does not exist")
        .with_code(404)
        .with_tracing();
    println!("   success = {}, code = {:?}", result.success, result.code);
    println!();

    println!("=== Demo complete ===");
    println!();
    println!("In a real application, you would use with_tracing() in your handlers:");
    println!();
    println!("  fn handler() -> ApiResult<User> {{");
    println!("      // ... business logic ...");
    println!("      ApiResult::fail(\"something went wrong\")");
    println!("          .with_code(500)");
    println!("          .with_tracing()");
    println!("  }}");
}
