/**
 * Non-side-effect class export for `<richtext-ui>`.
 *
 * Importing this file gives you the class(es) without auto-registering the tag.
 * Useful for test isolation, subclassing with tag-name override, or selective
 * composition.
 *
 * The auto-register path stays at `@adia-ai/web-components/components/richtext`
 * (which imports this file + calls `defineIfFree()`).
 *
 * @see ../../USAGE.md#registration--auto-vs-explicit
 */

import { UIElement } from '../../core/element.js';
import { renderMarkdown } from '../../core/markdown.js';

/**
 * <richtext-ui> — Renders markdown to styled HTML.
 *
 * Takes markdown as a `src` URL (fetched) or `markdown` property (inline),
 * converts it to HTML, and displays it with prose-appropriate typography.
 *
 * Usage:
 *   <richtext-ui src="/docs/readme.md"></richtext-ui>
 *   <richtext-ui markdown="# Hello\nSome **bold** text."></richtext-ui>
 *
 * Programmatic:
 *   const el = document.querySelector('richtext-ui');
 *   el.markdown = '# Title\nParagraph text.';
 */
export class UIRichText extends UIElement {
  static properties = {
    src:      { type: String, default: '', reflect: true },
    // Markdown bodies can be arbitrarily large; reflecting to the attribute
    // would bloat the DOM (and break parsing on multi-line content with
    // unescaped quotes). The property is the source of truth.
    markdown: { type: String, default: '', reflect: false },
  };

  static template = () => null;

  #bodyEl = null;
  #lastSrc = '';
  #lastMd = '';

  connected() {
    if (!this.#bodyEl) {
      this.#bodyEl = document.createElement('div');
      this.#bodyEl.setAttribute('data-richtext-body', '');
      this.appendChild(this.#bodyEl);
    }
  }

  render() {
    // Fetch from URL
    if (this.src && this.src !== this.#lastSrc) {
      this.#lastSrc = this.src;
      this.#lastMd = '';
      this.#load();
      return;
    }

    // Inline markdown
    if (this.markdown && this.markdown !== this.#lastMd) {
      this.#lastMd = this.markdown;
      this.#lastSrc = '';
      this.#bodyEl.innerHTML = renderMarkdown(this.markdown);
    }
  }

  async #load() {
    try {
      const res = await fetch(this.src);
      if (!this.isConnected) return;
      if (!res.ok) {
        this.#bodyEl.innerHTML = `<p>Failed to load: ${this.src}</p>`;
        return;
      }
      const md = await res.text();
      if (!this.isConnected) return;
      this.#bodyEl.innerHTML = renderMarkdown(md);
    } catch (e) {
      if (!this.isConnected) return;
      this.#bodyEl.innerHTML = `<p>Error: ${e.message}</p>`;
    }
  }
}
