import { readFileSync } from 'fs';
import path from 'path';
import type { ChapterView } from '../types.ts';

const TEMPLATE_PATH = path.resolve(process.cwd(), 'templates', 'book.template.html');

let templateCache: string | null = null;

function getTemplate(): string {
  if (!templateCache) templateCache = readFileSync(TEMPLATE_PATH, 'utf-8');
  return templateCache;
}

function escapeHtml(text: string): string {
  return text
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;');
}

function readChapterLines(filePath: string): string[] {
  try {
    const raw = readFileSync(filePath, 'utf-8');
    // Both plain-text and JSON chapters are read as plain text for HTML output,
    // matching the C# SomeBasicFileView.GetAsHTML() behaviour.
    try {
      const fragments = JSON.parse(raw) as Array<{ body: string }>;
      if (Array.isArray(fragments) && fragments.length > 0 && 'body' in (fragments[0] ?? {})) {
        return fragments.map(f => f.body).filter(Boolean);
      }
    } catch {
      // not JSON — fall through to plain text
    }
    return raw.split(/[\n\r]+/).map(l => l.trim()).filter(Boolean);
  } catch {
    return [];
  }
}

export function renderHtml(view: ChapterView): string {
  const template = getTemplate();

  const content = view.chapters
    .map((chapter, i) => {
      const chapNum = view.min + i;
      const lines = readChapterLines(chapter.path);
      if (lines.length === 0) return '';
      const paragraphs = lines
        .map((line, j) => `  <p id="para${chapNum}-${j}">${escapeHtml(line)}</p>`)
        .join('\n');
      return `<div id="chap${chapNum}">\n${paragraphs}\n</div>`;
    })
    .filter(Boolean)
    .join('\n');

  return template
    .replace('{id}', String(view.id))
    .replace('{min}', String(view.min))
    .replace('{max}', String(view.max))
    .replace('{content}', content);
}
