/*
 * Zernio API
 *
 * API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api
 *
 * The version of the OpenAPI document: 1.0.4
 * Contact: support@zernio.com
 * Generated by: https://openapi-generator.tech
 */

use crate::models;
use serde::{Deserialize, Serialize};

/// WorkflowNode : A node in a workflow graph. `config` shape depends on `type`.
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct WorkflowNode {
    /// Stable node id referenced by edges
    #[serde(rename = "id")]
    pub id: String,
    /// Node kind. The 16 supported types break into four groups:   messaging (send_message),   control flow (trigger, condition, delay, wait_for_reply, a_b_split, end),   data ops (set_variable, set_field, add_tag, remove_tag, enroll_sequence),   integrations (webhook, ai, handoff, start_call).
    #[serde(rename = "type")]
    pub r#type: Type,
    /// Type-specific settings. All string fields support `{{variable}}` interpolation against the run's variable bag (resolved at execution time).  **trigger**: `{ triggerType: inbound_message|api_call|whatsapp_event, keywords:[string], matchType: any|contains|exact|regex, onlyFirstMessage:boolean, eventType: message_sent|message_delivered|message_read|message_failed|reaction }`. Default `triggerType` is `inbound_message` for legacy nodes. `eventType` is only honored when `triggerType` is `whatsapp_event` (WhatsApp-only).  **send_message**: `{ messageType: text|template|media|interactive, text, template:{name,language,variableMapping}, media:{mediaType:image|video|audio|document, url,caption}, interactive }`. `template` and `interactive` are WhatsApp-only.  **wait_for_reply**: `{ timeoutMinutes:int (max 43200), saveAs:string }`. Resume via the `'reply'` edge on inbound, or `'timeout'` edge after `timeoutMinutes` of silence.  **condition**: `{ rules:[{ id, variable, operator: equals|not_equals|contains|not_contains|starts_with|ends_with|exists|not_exists|matches, value }] }`. First matching rule takes its `id` as the sourceHandle; otherwise `'default'`.  **set_variable**: `{ assignments:[{ name, value }] }`. Run-scoped (lives only for this execution; use `set_field` for persistent values).  **delay**: `{ delayMinutes:int (max 43200) }`. Suspends the run, resumes via timer.  **webhook**: `{ url, method: GET|POST|PUT|PATCH|DELETE, headers, bodyTemplate, saveAs }`. SSRF-guarded (private/loopback/metadata IPs rejected). Response saved as `{ status, ok, body }` to `vars[saveAs]`. Edge: `'success'` on 2xx, `'error'` otherwise.  **ai**: `{ provider: anthropic|openai|google|mistral|groq, model, preset: smart|tools|cheap, systemPrompt, userPromptTemplate, saveAs, temperature, maxTokens, outputType: text|json, tools:[{ name, description, parameters }] }`. Set `provider` + `model` for BYOK (uses your stored API key); omit `provider` for the legacy Telnyx path. Edges: `'success'`, `'tool:<name>'` (model picked a tool), `'error'`.  **handoff**: `{ note, assignTo }`. Terminates the run as `exited`, flags the conversation for a human operator.  **start_call**: `{ to, forwardTo, requirePermissionFirst, recordingEnabled, saveAs }`. WhatsApp-only. `forwardTo` can be `tel:+E164`, `sip:user@host`, or `wss://…` (AI voice agent). Edges: `'success'`, `'permission_required'`, `'failed'`.  **a_b_split**: `{ percentage: number 0-100 (default 50) }`. Random branch picker. Edges: `'a'` (with probability `percentage/100`), `'b'`.  **set_field**: `{ field, value }`. Persistent custom field on the Contact (vs `set_variable` which is run-scoped). Field name is sanitized to `[A-Za-z0-9_]`. No-op on `api_call` runs (no contact).  **enroll_sequence**: `{ sequenceId, saveAs }`. Enrolls the run's contact into a Sequence. Edges: `'success'`, `'error'`.  **add_tag** / **remove_tag**: `{ tag }`. Push or pull a tag on the Contact. No-op on `api_call` runs.  **end**: no config. Terminates the run as `completed`.
    #[serde(rename = "config", skip_serializing_if = "Option::is_none")]
    pub config: Option<std::collections::HashMap<String, serde_json::Value>>,
    #[serde(rename = "position", skip_serializing_if = "Option::is_none")]
    pub position: Option<Box<models::WorkflowNodePosition>>,
}

impl WorkflowNode {
    /// A node in a workflow graph. `config` shape depends on `type`.
    pub fn new(id: String, r#type: Type) -> WorkflowNode {
        WorkflowNode {
            id,
            r#type,
            config: None,
            position: None,
        }
    }
}
/// Node kind. The 16 supported types break into four groups:   messaging (send_message),   control flow (trigger, condition, delay, wait_for_reply, a_b_split, end),   data ops (set_variable, set_field, add_tag, remove_tag, enroll_sequence),   integrations (webhook, ai, handoff, start_call).
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum Type {
    #[serde(rename = "trigger")]
    Trigger,
    #[serde(rename = "send_message")]
    SendMessage,
    #[serde(rename = "wait_for_reply")]
    WaitForReply,
    #[serde(rename = "condition")]
    Condition,
    #[serde(rename = "set_variable")]
    SetVariable,
    #[serde(rename = "delay")]
    Delay,
    #[serde(rename = "webhook")]
    Webhook,
    #[serde(rename = "ai")]
    Ai,
    #[serde(rename = "handoff")]
    Handoff,
    #[serde(rename = "start_call")]
    StartCall,
    #[serde(rename = "a_b_split")]
    ABSplit,
    #[serde(rename = "set_field")]
    SetField,
    #[serde(rename = "enroll_sequence")]
    EnrollSequence,
    #[serde(rename = "add_tag")]
    AddTag,
    #[serde(rename = "remove_tag")]
    RemoveTag,
    #[serde(rename = "end")]
    End,
}

impl Default for Type {
    fn default() -> Type {
        Self::Trigger
    }
}
