export default function figcaptionPlugin(md) {
  // Rule to identify images followed by italicized text for figcaption
  function figcaptionRule(state) {
    const tokens = state.tokens;
    let figcaptionStartIndex = -1;

    for (let i = 0; i < tokens.length; i++) {
      // Check for paragraph containing only an image
      if (
        tokens[i].type === "paragraph_open" &&
        i + 2 < tokens.length &&
        tokens[i + 1].type === "inline" &&
        tokens[i + 1].children &&
        tokens[i + 1].children.length === 1 &&
        tokens[i + 1].children[0].type === "image" &&
        tokens[i + 2].type === "paragraph_close"
      ) {
        // Check if the next token is a paragraph starting with emphasis
        if (
          i + 5 < tokens.length &&
          tokens[i + 3].type === "paragraph_open" &&
          tokens[i + 4].type === "inline" &&
          tokens[i + 4].children &&
          tokens[i + 4].children.length > 0 &&
          tokens[i + 4].children[0].type === "em_open" &&
          tokens[i + 5].type === "paragraph_close"
        ) {
          figcaptionStartIndex = i + 3; // Start index of the caption paragraph

          // --- Replace tokens ---

          // 1. Change paragraph_open to figure_open
          const figureOpen = new state.Token("figure_open", "figure", 1);
          tokens[i] = figureOpen; // Replace paragraph_open

          // 2. Keep the inline token with the image as is (tokens[i+1])

          // 3. Change paragraph_close to figcaption_open
          const figcaptionOpen = new state.Token(
            "figcaption_open",
            "figcaption",
            1,
          );
          tokens[i + 2] = figcaptionOpen; // Replace paragraph_close

          // 4. Remove the caption's paragraph_open
          tokens.splice(figcaptionStartIndex, 1); // Remove paragraph_open at i+3

          // 5. Modify the caption's inline content: remove outer <em> tags
          const captionInlineToken = tokens[figcaptionStartIndex]; // Now at index i+3 after splice
          if (
            captionInlineToken.children[0].type === "em_open" &&
            captionInlineToken.children[captionInlineToken.children.length - 1]
              .type === "em_close"
          ) {
            captionInlineToken.children.shift(); // Remove em_open
            captionInlineToken.children.pop(); // Remove em_close
          }
          // Adjust level for caption content
          captionInlineToken.level += 1;
          captionInlineToken.children.forEach((child) => {
            child.level += 1;
          });

          // 6. Change the caption's paragraph_close to figcaption_close
          const figcaptionClose = new state.Token(
            "figcaption_close",
            "figcaption",
            -1,
          );
          tokens[figcaptionStartIndex + 1] = figcaptionClose; // Replace paragraph_close (now at i+4)

          // 7. Add figure_close after figcaption_close
          const figureClose = new state.Token("figure_close", "figure", -1);
          tokens.splice(figcaptionStartIndex + 2, 0, figureClose); // Insert figure_close (at i+5)

          // Adjust token index to skip the newly inserted/modified tokens
          i += 6; // Move past the figure structure
        }
      }
    }
  }

  md.core.ruler.after("inline", "figcaption", figcaptionRule);

  // Add renderer rules if they don't exist
  md.renderer.rules.figure_open =
    md.renderer.rules.figure_open ||
    function () {
      return "<figure>\n";
    };
  md.renderer.rules.figure_close =
    md.renderer.rules.figure_close ||
    function () {
      return "</figure>\n";
    };
  md.renderer.rules.figcaption_open =
    md.renderer.rules.figcaption_open ||
    function () {
      return "<figcaption>";
    };
  md.renderer.rules.figcaption_close =
    md.renderer.rules.figcaption_close ||
    function () {
      return "</figcaption>\n";
    };
}
