//! `dead_letters::` Rhai bridge.
//!
//! ```rhai
//! dead_letters::replay("01234567-...");           // re-enqueue + mark replayed
//! dead_letters::resolve("01234567-...", "ignored"); // close out the row
//! ```
//!
//! Sync↔async via `Handle::current().block_on(...)` — same pattern as
//! the `kv::` bridge (works because `LocalExecutorClient` runs the
//! script under `spawn_blocking`).
//!
//! `dead_letters::list(filter)` is intentionally NOT shipped — design
//! notes §4 defers it to v1.2 to align with the `docs::find()` query
//! DSL.

use std::str::FromStr;
use std::sync::Arc;

use super::bridge::block_on;
use picloud_shared::{DeadLetterId, SdkCallCx, Services};
use rhai::{Engine as RhaiEngine, EvalAltResult, Module};
use uuid::Uuid;

pub(super) fn register(engine: &mut RhaiEngine, services: &Services, cx: Arc<SdkCallCx>) {
    let svc = services.dead_letters.clone();
    let mut module = Module::new();
    {
        let svc = svc.clone();
        let cx = cx.clone();
        module.set_native_fn(
            "replay",
            move |id: &str| -> Result<(), Box<EvalAltResult>> {
                let dl_id = parse_dl_id(id)?;
                let svc = svc.clone();
                let cx = cx.clone();
                block_on("dead_letters", async move { svc.replay(&cx, dl_id).await })
            },
        );
    }
    {
        let svc = svc.clone();
        let cx = cx.clone();
        module.set_native_fn(
            "resolve",
            move |id: &str, reason: &str| -> Result<(), Box<EvalAltResult>> {
                let dl_id = parse_dl_id(id)?;
                let reason = reason.to_string();
                let svc = svc.clone();
                let cx = cx.clone();
                block_on("dead_letters", async move {
                    svc.resolve(&cx, dl_id, &reason).await
                })
            },
        );
    }
    engine.register_static_module("dead_letters", module.into());
}

fn parse_dl_id(s: &str) -> Result<DeadLetterId, Box<EvalAltResult>> {
    Uuid::from_str(s)
        .map(DeadLetterId::from)
        .map_err(|e| -> Box<EvalAltResult> {
            EvalAltResult::ErrorRuntime(
                format!("dead_letters: invalid id {s:?}: {e}").into(),
                rhai::Position::NONE,
            )
            .into()
        })
}
