import { flow, pipe } from "fp-ts-esm/function";
import * as O from "fp-ts-esm/Option";
import * as R from "fp-ts-esm/Record";
import {
  Decoration_Type,
  Node_Type,
  PluginContainerData_Alignment,
  TextStyle_TextAlignment
} from "./../../../../../ricos-schema/legacy/wix/rich_content/v1/index.js";
import { CHECKBOX_LIST_STYLE_ATTRIBUTE_VALUE } from "./../../../../../_shared/list-checkbox/checkbox-list-style.js";
import { and } from "../../../../fp-utils.js";
import {
  createHeadingNode,
  createLink,
  createNode,
  createParagraphNode,
  createTextNode
} from "../../../node-utils.js";
import {
  getAttributes,
  getChildNodes,
  getStyle,
  hasStyleFor,
  hasTag,
  isText,
  oneOf,
  toName
} from "./parse5-utils.js";
const isCheckboxListElement = (element) => getAttributes(element)["data-list-style"]?.toLowerCase() === CHECKBOX_LIST_STYLE_ATTRIBUTE_VALUE || getChildNodes(element).some((child) => {
  if (child.nodeName !== "li") {
    return false;
  }
  const childAttrs = getAttributes(child);
  return childAttrs["role"] === "checkbox" || "aria-checked" in childAttrs;
});
const identityRule = [
  () => true,
  ({ visit }) => (
    // @ts-ignore $TSFixMe
    (node) => visit(node)
  )
];
const textToText = [
  isText,
  // @ts-ignore $TSFixMe
  (context) => (node) => {
    const textNode = [createTextNode(node.value, context.decorations)];
    return node.parentNode.nodeName === "li" ? [createParagraphNode(textNode)] : textNode;
  }
];
const pToParagraph = [
  hasTag("p"),
  // @ts-ignore $TSFixMe
  (context) => (el) => pipe(
    el,
    getStyle,
    O.chain(R.lookup("text-align")),
    O.map(toTextStyle),
    O.fold(
      () => [createParagraphNode(context.visit(el))],
      (textStyle) => [createParagraphNode(context.visit(el), { textStyle })]
    )
  )
];
const hToHeading = [
  flow(toName, /h[1-6]/.test.bind(/h[1-6]/)),
  // @ts-ignore $TSFixMe
  (context) => (node) => [
    createHeadingNode(context.visit(node), {
      level: Number(node.nodeName.replace("h", ""))
    })
  ]
];
const aToLink = [
  // @ts-ignore $TSFixMe
  and([hasTag("a"), flow(getAttributes, ({ href }) => !href?.startsWith("#"))]),
  // @ts-ignore $TSFixMe
  (context) => (node) => {
    const attrs = getAttributes(node);
    return context.addDecoration(
      Decoration_Type.LINK,
      { linkData: { link: createLink({ ...attrs, url: attrs.href }) } },
      node
    );
  }
];
const aToAnchor = [
  // @ts-ignore $TSFixMe
  and([hasTag("a"), flow(getAttributes, ({ href }) => !!href && href.startsWith("#"))]),
  // @ts-ignore $TSFixMe
  (context) => (node) => {
    const attrs = getAttributes(node);
    return context.addDecoration(
      Decoration_Type.ANCHOR,
      { anchorData: { ...attrs, anchor: attrs.href.substr(1) } },
      node
    );
  }
];
const lToList = [
  oneOf(["ul", "ol", "li"]),
  // @ts-ignore $TSFixMe
  (context) => (node) => {
    const attrs = getAttributes(node);
    const nodeType = {
      ul: isCheckboxListElement(node) ? Node_Type.CHECKBOX_LIST : Node_Type.BULLETED_LIST,
      ol: Node_Type.ORDERED_LIST,
      li: Node_Type.LIST_ITEM
    }[node.nodeName];
    if (!nodeType) {
      return [];
    }
    const checked = attrs["aria-checked"];
    const listItemData = nodeType === Node_Type.LIST_ITEM && (checked === "true" || checked === "false") ? { listItemData: { checked: checked === "true" } } : {};
    const listData = nodeType !== Node_Type.LIST_ITEM ? { indentation: 0 } : {};
    return [
      {
        ...createNode(nodeType, {
          nodes: nodeType === Node_Type.LIST_ITEM && node.childNodes.length === 0 ? [createParagraphNode()] : context.visit(node),
          data: listData
        }),
        ...listItemData
      }
    ];
  }
];
const strongEmUStrikeToDecoration = [
  oneOf(["strong", "em", "u", "s", "strike", "del"]),
  // @ts-ignore $TSFixMe
  (context) => (node) => {
    const decorationType = {
      strong: Decoration_Type.BOLD,
      em: Decoration_Type.ITALIC,
      u: Decoration_Type.UNDERLINE,
      s: Decoration_Type.STRIKETHROUGH,
      strike: Decoration_Type.STRIKETHROUGH,
      del: Decoration_Type.STRIKETHROUGH
    }[node.nodeName];
    if (!decorationType) {
      return [];
    }
    return context.addDecoration(decorationType, {}, node);
  }
];
const toForegroundData = (color) => ({
  foreground: color
});
const toBackgroundData = (color) => ({
  background: color
});
const toTextAlignment = (textAlign) => {
  switch (textAlign) {
    case "left":
      return TextStyle_TextAlignment.LEFT;
    case "right":
      return TextStyle_TextAlignment.RIGHT;
    case "center":
      return TextStyle_TextAlignment.CENTER;
    case "justify":
      return TextStyle_TextAlignment.JUSTIFY;
    default:
      return TextStyle_TextAlignment.AUTO;
  }
};
const toTextStyle = (style) => {
  const textAlignment = toTextAlignment(style);
  return { textAlignment };
};
const toColorDecoration = (ctx, el) => (colorData) => ctx.addDecoration(Decoration_Type.COLOR, { colorData }, el);
const colorStyleToTextColor = [
  // @ts-ignore $TSFixMe
  and([hasTag("span"), hasStyleFor("color")]),
  // @ts-ignore $TSFixMe
  (context) => (el) => pipe(
    el,
    getStyle,
    O.chain(R.lookup("color")),
    // @ts-ignore $TSFixMe
    O.map(toForegroundData),
    O.fold(() => [], toColorDecoration(context, el))
  )
];
const spanToMention = [
  // @ts-ignore $TSFixMe
  and([hasTag("span"), flow(getAttributes, (attrs) => !!attrs["data-mention-name"])]),
  // @ts-ignore $TSFixMe
  (context) => (node) => {
    const {
      "data-mention-name": name,
      "data-mention-slug": slug,
      "data-mention-id": id
    } = getAttributes(node);
    return context.addDecoration(
      Decoration_Type.MENTION,
      { mentionData: { name, slug, id } },
      node
    );
  }
];
const spanToSpoiler = [
  // @ts-ignore $TSFixMe
  and([hasTag("span"), flow(getAttributes, (attrs) => !!attrs["data-spoiler"])]),
  // @ts-ignore $TSFixMe
  (context) => (node) => context.addDecoration(Decoration_Type.SPOILER, {}, node)
];
const backgroundStyleToTextHighlight = [
  // @ts-ignore $TSFixMe
  and([hasTag("span"), hasStyleFor("background-color")]),
  // @ts-ignore $TSFixMe
  (context) => (el) => pipe(
    el,
    getStyle,
    O.chain(R.lookup("background-color")),
    // @ts-ignore $TSFixMe
    O.map(toBackgroundData),
    O.fold(() => [], toColorDecoration(context, el))
  )
];
const toImageData = (decorations, node) => {
  const attrs = getAttributes(node);
  return {
    image: {
      src: { url: attrs.src },
      ...attrs.width && { width: Number(attrs.width) },
      ...attrs.height && { height: Number(attrs.height) }
    },
    ...attrs.width ? {
      containerData: {
        alignment: PluginContainerData_Alignment.CENTER,
        width: { size: void 0, custom: attrs.width }
      }
    } : {},
    altText: attrs.alt,
    link: decorations.filter(({ type }) => type === Decoration_Type.LINK).map(({ linkData }) => linkData?.link)[0]
  };
};
const imgToImage = [
  hasTag("img"),
  // @ts-ignore $TSFixMe
  (context) => (node) => [
    createNode(Node_Type.IMAGE, {
      nodes: [],
      data: toImageData(context.decorations, node)
    })
  ]
];
export {
  aToAnchor,
  aToLink,
  backgroundStyleToTextHighlight,
  colorStyleToTextColor,
  hToHeading,
  identityRule,
  imgToImage,
  lToList,
  pToParagraph,
  spanToMention,
  spanToSpoiler,
  strongEmUStrikeToDecoration,
  textToText
};
//# sourceMappingURL=rules.js.map
