/**
 * Shared engine-to-client turn protocol.
 */
import { parseTag } from '../utils/tag-parser';

export type InputMode = 'text' | 'choice' | 'end';

export interface StoryTag {
  key: string;
  value?: string;
  param?: string;
}

export interface ParagraphResult {
  text: string;
  tags: StoryTag[];
}

export interface ChoiceResult {
  index: number;
  text: string;
  tags: StoryTag[];
  category?: string;
  letter?: string;
}

export interface TurnResult {
  turnId: number;
  paragraphs: ParagraphResult[];
  choices: ChoiceResult[];
  inputMode: InputMode;
  globalTags?: StoryTag[];
  gameState?: {
    currentRoomId?: string;
    score?: number;
    moves?: number;
    statusLine?: string;
    endState?: {
      type: 'intended' | 'error';
      message?: string;
    };
  };
  suggestions?: string[];
}

export function textToParagraphs(text: string, tags: StoryTag[] = []): ParagraphResult[] {
  return String(text || '')
    .replace(/\r\n?/g, '\n')
    .split(/\n{2,}/)
    .map((paragraph) => paragraph.trim())
    .filter(Boolean)
    .map((paragraph) => {
      const lines = paragraph.split('\n');
      const paragraphTags: StoryTag[] = [...tags];
      const textLines: string[] = [];
      let tagPrefixOpen = true;

      for (const line of lines) {
        const trimmed = line.trim();
        const maybeTag = tagPrefixOpen && trimmed.startsWith('#') ? parseTag(trimmed) : null;

        if (maybeTag) {
          paragraphTags.push(maybeTag);
        } else {
          tagPrefixOpen = false;
          textLines.push(line);
        }
      }

      return {
        text: textLines.join('\n').trim(),
        tags: paragraphTags,
      };
    });
}
