"use strict";

import React, { Fragment } from "react";
import { View } from "react-native";
import { Banner } from "../banner";
import { Divider, HSpacer, VSpacer } from "../layout";
import { Body } from "../typography/Body";
import { BodyMonospace } from "../typography/BodyMonospace";
import { H1 } from "../typography/H1";
import { H2 } from "../typography/H2";
import { H3 } from "../typography/H3";
import { H4 } from "../typography/H4";
import { H5 } from "../typography/H5";
import { H6 } from "../typography/H6";
import { IOText } from "../typography/IOText";
import { CodeBlock } from "./CodeBlock";
import { ImageRenderer } from "./ImageRenderer";
import { collectRawText, extractPictogramName, getOrderedListMarker, getUnorderedListBullet, isBrTag, stripPictogramPrefix } from "./utils";

/* ─── Inline flattening (shared between heading and paragraph rendering) ─── */
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
/**
 * Recursively walks inline AST nodes and produces flat styled segments
 * with accumulated bold/italic/link state.
 */
const flattenInlineNodes = (nodes, inherited) => nodes.reduce((acc, node) => {
  switch (node.type) {
    case "text":
    case "code_inline":
      return [...acc, {
        key: node.key,
        text: node.content ?? "",
        style: inherited
      }];
    case "softbreak":
    case "hardbreak":
      return [...acc, {
        key: node.key,
        text: "\n",
        style: inherited
      }];
    case "strong":
      return [...acc, ...flattenInlineNodes(node.children, {
        ...inherited,
        bold: true
      })];
    case "em":
      return [...acc, ...flattenInlineNodes(node.children, {
        ...inherited,
        italic: true
      })];
    case "link":
      {
        const href = node.attributes?.href;
        return [...acc, ...flattenInlineNodes(node.children, {
          ...inherited,
          link: href
        })];
      }
    default:
      return acc;
  }
}, []);

/**
 * Renders a single styled segment as either a raw string
 * or an IOText element with the appropriate props.
 */
const renderSegment = (segment, context, isCode) => {
  if (isCode) {
    return /*#__PURE__*/_jsx(BodyMonospace, {
      children: segment.text
    }, segment.key);
  }
  const {
    bold,
    italic,
    link
  } = segment.style;
  return /*#__PURE__*/_jsx(IOText, {
    ...(bold ? {
      weight: "Semibold"
    } : {}),
    ...(italic ? {
      fontStyle: "italic"
    } : {}),
    ...(link ? {
      color: context.linkColor,
      onPress: () => context.onLinkPress?.(link),
      accessibilityRole: "link",
      textStyle: {
        textDecorationLine: "underline"
      }
    } : {}),
    size: context.fontSize,
    lineHeight: context.lineHeight,
    children: segment.text
  }, segment.key);
};

/* ─── Heading component map ─── */

const headingComponentMap = {
  heading1: H1,
  heading2: H2,
  heading3: H3,
  heading4: H4,
  heading5: H5,
  heading6: H6
};

/* ─── Block rendering helpers ─── */

/**
 * Renders a paragraph block by flattening inline children
 * into styled segments.
 */
const renderParagraph = (node, context) => {
  const segments = flattenInlineNodes(node.children, {
    bold: false,
    italic: false
  });
  return /*#__PURE__*/_jsx(Body, {
    style: {
      textAlign: context.textAlign
    },
    children: segments.map(seg => {
      const matchingNode = node.children.find(c => c.key === seg.key);
      const isCode = matchingNode?.type === "code_inline";
      return renderSegment(seg, context, isCode);
    })
  }, node.key);
};

/**
 * Creates a render rule for a heading level using the corresponding
 * DS heading component (H1-H6). This ensures headings inherit
 * dynamicTypeRamp, uppercase/letterSpacing (H5), legacy typeface (H6),
 * and theme colors automatically.
 */
const makeHeadingRule = Heading => (node, _renderChildren, context) => {
  const segments = flattenInlineNodes(node.children, {
    bold: false,
    italic: false
  });
  return /*#__PURE__*/_jsx(View, {
    accessibilityRole: "header",
    children: /*#__PURE__*/_jsx(Heading, {
      style: {
        textAlign: context.textAlign
      },
      children: segments.map(seg => seg.text)
    })
  }, node.key);
};

/* ─── Default render rules ─── */

const paragraphRule = (node, _renderChildren, context) => renderParagraph(node, context);
const textRule = node => /*#__PURE__*/_jsx(Fragment, {
  children: node.content ?? ""
}, node.key);
const strongRule = (node, renderChildren) => /*#__PURE__*/_jsx(IOText, {
  weight: "Semibold",
  children: renderChildren(node.children)
}, node.key);
const emRule = (node, renderChildren) => /*#__PURE__*/_jsx(IOText, {
  fontStyle: "italic",
  children: renderChildren(node.children)
}, node.key);
const linkRule = (node, renderChildren, context) => {
  const href = node.attributes?.href;
  return /*#__PURE__*/_jsx(IOText, {
    color: context.linkColor,
    onPress: href ? () => context.onLinkPress?.(href) : undefined,
    accessibilityRole: "link",
    textStyle: {
      textDecorationLine: "underline"
    },
    children: renderChildren(node.children)
  }, node.key);
};
const softbreakRule = node => /*#__PURE__*/_jsx(Fragment, {
  children: "\n"
}, node.key);
const hardbreakRule = node => /*#__PURE__*/_jsx(Fragment, {
  children: "\n"
}, node.key);
const bulletListRule = (node, renderChildren) => /*#__PURE__*/_jsxs(View, {
  accessible: true,
  accessibilityRole: "list",
  style: {
    paddingLeft: 12
  },
  children: [/*#__PURE__*/_jsx(VSpacer, {
    size: 8
  }), node.children.map(child => /*#__PURE__*/_jsxs(View, {
    style: {
      flexDirection: "row"
    },
    children: [/*#__PURE__*/_jsx(Body, {
      children: getUnorderedListBullet(node.listDepth ?? 0)
    }), /*#__PURE__*/_jsx(HSpacer, {
      size: 8
    }), /*#__PURE__*/_jsx(View, {
      style: {
        flex: 1,
        flexShrink: 1
      },
      children: renderChildren(child.children)
    })]
  }, child.key)), /*#__PURE__*/_jsx(VSpacer, {
    size: 8
  })]
}, node.key);
const orderedListRule = (node, renderChildren) => /*#__PURE__*/_jsxs(View, {
  accessible: true,
  accessibilityRole: "list",
  style: {
    paddingLeft: 12
  },
  children: [/*#__PURE__*/_jsx(VSpacer, {
    size: 8
  }), node.children.map((child, i) => /*#__PURE__*/_jsxs(View, {
    style: {
      flexDirection: "row"
    },
    children: [/*#__PURE__*/_jsx(Body, {
      children: getOrderedListMarker(i + 1, node.listDepth ?? 0)
    }), /*#__PURE__*/_jsx(HSpacer, {
      size: 8
    }), /*#__PURE__*/_jsx(View, {
      style: {
        flex: 1,
        flexShrink: 1
      },
      children: renderChildren(child.children)
    })]
  }, child.key)), /*#__PURE__*/_jsx(VSpacer, {
    size: 8
  })]
}, node.key);
const listItemRule = (node, renderChildren) => /*#__PURE__*/_jsx(View, {
  style: {
    flex: 1,
    flexShrink: 1
  },
  children: renderChildren(node.children)
}, node.key);
const blockquoteRule = node => {
  const allText = collectRawText(node);
  const pictogramName = extractPictogramName(allText);

  // Find the first heading child for the banner title
  const headingNode = node.children.find(c => c.type.startsWith("heading"));
  const title = headingNode ? collectRawText(headingNode).trim() : undefined;

  // Collect content from paragraph children, stripping the pictogram pattern
  const content = node.children.filter(c => c.type === "paragraph").map(c => stripPictogramPrefix(collectRawText(c)).trim()).filter(Boolean).join("\n");
  return /*#__PURE__*/_jsx(Banner, {
    pictogramName: pictogramName,
    color: "neutral",
    title: title,
    content: content || undefined
  }, node.key);
};
const imageRule = node => /*#__PURE__*/_jsx(View, {
  style: {
    marginVertical: 16
  },
  children: /*#__PURE__*/_jsx(ImageRenderer, {
    node: node
  })
}, node.key);
const codeInlineRule = node => /*#__PURE__*/_jsx(BodyMonospace, {
  children: node.content ?? ""
}, node.key);
const fenceRule = node => /*#__PURE__*/_jsx(CodeBlock, {
  content: (node.content ?? "").trimEnd()
}, node.key);
const hrRule = node => /*#__PURE__*/_jsx(Divider, {}, node.key);
const htmlRule = node => {
  if (node.content && isBrTag(node.content)) {
    return /*#__PURE__*/_jsx(Fragment, {
      children: "\n"
    }, node.key);
  }
  return null;
};

/**
 * The complete set of default render rules for all supported node types.
 */
export const DEFAULT_RULES = {
  heading1: makeHeadingRule(headingComponentMap.heading1),
  heading2: makeHeadingRule(headingComponentMap.heading2),
  heading3: makeHeadingRule(headingComponentMap.heading3),
  heading4: makeHeadingRule(headingComponentMap.heading4),
  heading5: makeHeadingRule(headingComponentMap.heading5),
  heading6: makeHeadingRule(headingComponentMap.heading6),
  paragraph: paragraphRule,
  text: textRule,
  strong: strongRule,
  em: emRule,
  link: linkRule,
  softbreak: softbreakRule,
  hardbreak: hardbreakRule,
  bullet_list: bulletListRule,
  ordered_list: orderedListRule,
  list_item: listItemRule,
  blockquote: blockquoteRule,
  image: imageRule,
  code_inline: codeInlineRule,
  fence: fenceRule,
  hr: hrRule,
  html_block: htmlRule,
  html_inline: htmlRule
};
//# sourceMappingURL=rules.js.map