-- Utterances: the content of a dialogue node (and utterance-bearing cutscenes).
-- One table for both NPC lines and player choices, distinguished by `utterer`.
-- The intra-node conversation graph uses two self-references; `terminal_id` is the
-- exit that leaves the node via one of its output terminals. Runtime is Phase 2.

CREATE TABLE osint.utterances (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  node_id UUID NOT NULL REFERENCES osint.story_nodes(id) ON DELETE CASCADE,
  utterer TEXT NOT NULL DEFAULT 'npc' CHECK (utterer IN ('npc','player')),
  npc_id UUID REFERENCES osint.npcs(id),   -- speaker for NPC lines; NULL for player choices
  pose_key TEXT,                            -- resolved with the usual pose fallback
  text TEXT NOT NULL DEFAULT '',
  -- Intra-node conversation graph:
  parent_utterance_id UUID REFERENCES osint.utterances(id) ON DELETE CASCADE,       -- player options hang under the NPC prompt they answer
  advances_to_utterance_id UUID REFERENCES osint.utterances(id) ON DELETE SET NULL, -- next line; may loop back to the same one
  -- Inter-node exit:
  terminal_id UUID REFERENCES osint.story_node_terminals(id) ON DELETE SET NULL,
  effect TEXT,                              -- optional authored side-effect hook (vocabulary TBD)
  xpos DOUBLE PRECISION NOT NULL DEFAULT 0, -- position in the node's utterance sub-canvas
  ypos DOUBLE PRECISION NOT NULL DEFAULT 0,
  sort_order INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX utterances_node_idx ON osint.utterances (node_id);

COMMENT ON TABLE osint.utterances IS 'Dialogue content per story node. Same-node integrity for parent/advances_to/terminal links is enforced in the repository (Phase 1).';
