//! AFI fixture — Rust port of `tests/afi/fixture.py`.
//!
//! Same 7 functions, same 5 shared types, same context+affects+merge graph.
//! The KDL emitted by `build_ir()` against this registry is byte-identical
//! to the canonical Python-emitted `protocol/mizan-codegen/tests/fixtures/
//! afi_ir.kdl` — gated by the three-way codegen-parity test.

use mizan_core as mizan;
use mizan_core::prelude::*;
use mizan_core::RequestHandle;
use serde::{Deserialize, Serialize};

#[derive(Mizan, Serialize, Deserialize, Debug, Clone)]
pub struct EchoOutput {
    pub message: String,
}

#[derive(Mizan, Serialize, Deserialize, Debug, Clone)]
pub struct WhoamiOutput {
    pub email: String,
    pub authenticated: bool,
}

#[derive(Mizan, Serialize, Deserialize, Debug, Clone)]
pub struct ProfileOutput {
    pub user_id: i64,
    pub name: String,
}

#[derive(Mizan, Serialize, Deserialize, Debug, Clone)]
pub struct OrderOutput {
    pub id: i64,
    pub user_id: i64,
    pub total: i64,
}

#[derive(Mizan, Serialize, Deserialize, Debug, Clone)]
pub struct StatusOutput {
    pub ok: bool,
}

#[mizan::context("user")]
pub struct UserCtx;

#[mizan::client]
pub async fn echo(_req: &RequestHandle<'_>, text: String) -> EchoOutput {
    EchoOutput {
        message: format!("echo: {text}"),
    }
}

#[mizan::client]
pub async fn whoami(_req: &RequestHandle<'_>) -> WhoamiOutput {
    WhoamiOutput {
        email: "anon@example.com".into(),
        authenticated: false,
    }
}

#[mizan::client(context = UserCtx)]
pub async fn user_profile(_req: &RequestHandle<'_>, user_id: i64) -> ProfileOutput {
    ProfileOutput {
        user_id,
        name: "placeholder".into(),
    }
}

#[mizan::client(context = UserCtx)]
pub async fn user_orders(_req: &RequestHandle<'_>, _user_id: i64) -> Vec<OrderOutput> {
    vec![]
}

#[mizan::client(affects = UserCtx)]
pub async fn update_profile(
    _req: &RequestHandle<'_>,
    _user_id: i64,
    _name: String,
) -> StatusOutput {
    StatusOutput { ok: true }
}

#[mizan::client]
pub async fn find_user(_req: &RequestHandle<'_>, _user_id: i64) -> Option<ProfileOutput> {
    None
}

#[mizan::client(merge = UserCtx)]
pub async fn rename_user(
    _req: &RequestHandle<'_>,
    user_id: i64,
    name: String,
) -> ProfileOutput {
    ProfileOutput { user_id, name }
}
