src/datastar_gleam.gleam

/// The core Datastar event type and SSE wire-format serializer.
///
/// This module provides the `DatastarEvent` type and the `to_string` function
/// used by all framework integrations. You typically won't need to construct
/// `DatastarEvent` values directly — use `datastar/event` builders instead.

import datastar_gleam/consts.{type EventType}
import gleam/int
import gleam/list
import gleam/option.{type Option}
import gleam/string

/// A single Datastar SSE event.
///
/// `event` – the Datastar event type (`PatchElements` or `PatchSignals`).
/// `id` – optional SSE event ID.
/// `retry` – reconnection time in milliseconds (default `1000`).
/// `data` – list of data lines that make up the event payload.
pub type DatastarEvent {
  DatastarEvent(
    event: EventType,
    id: Option(String),
    retry: Int,
    data: List(String),
  )
}

/// The default SSE retry duration used by Datastar (1000 ms).
pub fn default_retry() -> Int {
  1000
}

/// Serialize a `DatastarEvent` to the SSE wire format.
///
/// ```gleam
/// import datastar
/// import datastar/event
///
/// let ev =
///   event.new_elements("<div>Hello!</div>")
///   |> event.patch_elements_to_datastar_event()
///
/// let text = datastar.to_string(ev)
/// // => "event: datastar-patch-elements\ndata: elements <div>Hello!</div>\n\n"
/// ```
pub fn to_string(ev: DatastarEvent) -> String {
  let base = "event: " <> consts.event_type_string(ev.event)
  let base = case ev.id {
    option.Some(i) -> base <> "\nid: " <> i
    option.None -> base
  }
  let base = case ev.retry {
    1000 -> base
    n -> base <> "\nretry: " <> int.to_string(n)
  }
  let data_lines = list.map(ev.data, fn(line) { "data: " <> line })
  let body = string.join(data_lines, with: "\n")
  base <> "\n" <> body <> "\n\n"
}