import { Marked } from "marked";
const widget_map = {
  inline: {
    roll: () => import("~/components/viewer/widgets/inline/RollWidgetInline.vue"),
  },
  display: {
    roll: () => import("~/components/viewer/widgets/display/RollWidgetDisplay.vue"),
  } 
};

const componentCache = {
  inline: {},
  display: {}
}

const GetWidget = (type, name) => {
  if (!componentCache[type][name]) {
    componentCache[type][name] = defineAsyncComponent(
      widget_map[type][name]
    )
  }

  return componentCache[type][name]
}


const marker = new Marked();

const extension = {
  name: "widget",
  level: "block",

  tokenizer(src) {
    const rule = /^@(\w+)\n([\s\S]+?)\n@end/;
    const match = rule.exec(src);

    if (!match) return;

    return {
      type: "widget",
      raw: match[0],
      name: match[1],
      text: match[2],
    };
  },

  renderer(token) {
    return `<div class="vue-component-display" data-component="${token.name}" data-content="${token.text}"></div>`;
  },
};

const inlineExtension = {
  name: "widget_inline",
  level: "inline",
  start(src) {
    return src.indexOf("@");
  },

  tokenizer(src) {
    const rule = /^@(\w+)\s*\[([^\]]*)\]/;
    const match = rule.exec(src);
    if (!match) return;

    return {
      type: "widget_inline",
      raw: match[0],
      name: match[1],
      text: match[2],
    };
  },

  renderer(token) {
    return `<span class="vue-component-inline" data-component="${token.name}" data-content="${token.text}"></span>`;
  },
};

const linkExtension = {
  name: "link_to",
  level: "inline",
  start(src) {
    return src.indexOf("[[");
  },

  tokenizer(src) {
    const rule = /^\[\[([^\n]*)\]\]/;
    const match = rule.exec(src);
    if (!match) return;

    return {
      type: "link_to",
      raw: match[0],
      link: match[1],
    };
  },

  renderer(token) {
    return `<span class="vue-link" data-href="${token.link}">Link</span>`;
  },
};

marker.use({
  extensions: [extension, inlineExtension, linkExtension],
});

function ParseMarkdown(source) {
  return marker.parse(source || "");
}

export { ParseMarkdown, GetWidget };