import { Marked, type RendererObject } from "marked";
import { decode } from "tiny-decode";

const renderer: RendererObject = {
  code({ text }) {
    return `\n${text}\n`;
  },
  blockquote({ tokens }) {
    return `\n> ${this.parser.parseInline(tokens)}\n`;
  },
  html() {
    return "";
  },
  heading({ tokens }) {
    return `\n== ${this.parser.parseInline(tokens)} ==\n`;
  },
  hr() {
    return `\n***\n`;
  },
  list({ items }) {
    return `\n${items.map(this.listitem).join("\n")}\n`;
  },
  listitem({ tokens }) {
    return `- ${this.parser.parseInline(tokens)}\n`;
  },
  checkbox(token) {
    console.error("ERROR: unhandled token in markdownToPlaintext.checkbox", token);
    throw new Error("Not supported by plaintext renderer: checkbox");
  },
  paragraph({ tokens }) {
    return `\n${this.parser.parseInline(tokens)}\n`;
  },
  table({ header, rows }) {
    return `\n${this.tablerow({ text: header.map(this.tablecell).join(" | ") })}\n---\n${rows
      .map((row) => this.tablerow({ text: row.map(this.tablecell).join(" | ") }))
      .join("\n")}\n`;
  },
  tablerow({ text }) {
    return text;
  },
  tablecell({ tokens }) {
    return this.parser.parseInline(tokens);
  },
  strong({ tokens }) {
    return this.parser.parseInline(tokens);
  },
  em({ tokens }) {
    return `_${this.parser.parseInline(tokens)}_`;
  },
  codespan({ text }) {
    return text;
  },
  br() {
    return "\n\n";
  },
  del(token) {
    console.error("ERROR: unhandled token in markdownToPlaintext.del", token);
    throw new Error("Not supported by plaintext renderer: del");
  },
  link({ tokens }) {
    return this.parser.parseInline(tokens);
  },
  image() {
    return "";
  },
};

const plaintextRenderer = new Marked({ renderer, async: false });

export const markdownToPlaintext = (text: string) => decode(plaintextRenderer.parse(text, { async: false }).trim());
