namespace Rune.Messages.Contracts;

/// <summary>
/// <para>
/// Channel message contract for the inbound webhook delivery.
/// Mirrors the <c>Morgana.AI.Records.ChannelMessage</c> schema emitted by Morgana's
/// <c>WebhookChannelService</c> via <c>POST {callbackUrl}</c>.
/// </para>
/// <para>
/// CONTRACT VERSION: 1.0<br/>
/// SYNC WITH: Morgana.AI (Records.ChannelMessage)
/// </para>
/// <para>
/// ⚠️ IMPORTANT: This DTO is duplicated in Morgana (Morgana.AI.Records.ChannelMessage).
/// When making changes, update both versions in lockstep — there is no shared contracts project.
/// </para>
/// </summary>
public sealed class ChannelMessage
{
    /// <summary>Unique identifier of the conversation this message belongs to.</summary>
    public string ConversationId { get; set; } = string.Empty;

    /// <summary>Message text to display to the user.</summary>
    public string Text { get; set; } = string.Empty;

    /// <summary>UTC timestamp when this message was generated by the backend.</summary>
    public DateTime Timestamp { get; set; }

    /// <summary>
    /// Type of message for UI rendering and styling.
    /// Valid values: "assistant", "presentation", "system", "system_warning", "error"
    /// </summary>
    public string MessageType { get; set; } = "assistant";

    /// <summary>
    /// Optional list of quick reply buttons. For Rune (SupportsQuickReplies=false) Morgana's
    /// channel adapter strips these before delivery, so the list is expected to be null/empty;
    /// the contract is kept intact for binary compatibility.
    /// </summary>
    public List<QuickReply>? QuickReplies { get; set; }

    /// <summary>
    /// Optional rich card. For Rune (SupportsRichCards=false) Morgana's channel adapter strips
    /// this before delivery, so the field is expected to be null; the contract is kept intact
    /// for binary compatibility.
    /// </summary>
    public RichCard? RichCard { get; set; }

    /// <summary>Optional error reason code when MessageType is "error" or "system_warning".</summary>
    public string? ErrorReason { get; set; }

    /// <summary>
    /// Name of the agent that generated this message.
    /// Examples: "Morgana", "Morgana (Billing)", "Morgana (Technical Support)".
    /// Rune uses this to drive the sticky header's colored speaker label.
    /// </summary>
    public string AgentName { get; set; } = "Morgana";

    /// <summary>Indicates whether this specialized agent has completed its task.</summary>
    public bool AgentCompleted { get; set; }

    /// <summary>
    /// Duration of the eventual fading message — Rune ignores it since the CLI has no fading UI.
    /// </summary>
    public int? FadingMessageDurationSeconds { get; set; } = 10;

    /// <summary>
    /// Conversation-level metadata (e.g. remaining dust budget). Characterises the
    /// conversation, not this message. Rune renders it in the sticky header.
    /// Null when no such metadata is available (dust limiting disabled).
    /// </summary>
    public ConversationMetadata? ConversationMetadata { get; set; }
}
