import type {Program as EstreeProgram} from 'estree'
import type {Data as UnistData} from 'unist'

interface EsastData extends UnistData {
  /**
   * Whether a node was authored as explicit JSX (`<h1>`) or as implicitly
   * turned into JSX (`# hi`).
   *
   * Registered by `@mdx-js/mdx/lib/types.d.ts`.
   */
  _mdxExplicitJsx?: boolean | null | undefined
}

interface EsastCommentData extends EsastData {
  /**
   * Whether a node (only used on comments) was generated by us to include the
   * JSX pragmas, so that when we compile JSX away, we can remove it.
   *
   * Registered by `@mdx-js/mdx/lib/types.d.ts`.
   */
  _mdxIsPragmaComment?: boolean | null | undefined
}

// Register data on `estree`.
declare module 'estree' {
  interface BaseNode {
    /**
     * Extra unist data passed through from mdast through hast to esast.
     *
     * Registered by `@mdx-js/mdx/lib/types.d.ts`.
     */
    data?: EsastData | undefined
  }

  interface Comment {
    /**
     * Extra unist data added by `recma-document`.
     *
     * Registered by `@mdx-js/mdx/lib/types.d.ts`.
     */
    data?: EsastCommentData | undefined
  }
}

// Register data on `mdast`.
declare module 'mdast-util-mdx-jsx' {
  interface MdxJsxFlowElementData {
    /**
     * Whether a node was authored as explicit JSX (`<h1>`) or as implicitly
     * turned into JSX (`# hi`).
     *
     * Registered by `@mdx-js/mdx/lib/types.d.ts`.
     */
    _mdxExplicitJsx?: boolean | null | undefined
  }

  interface MdxJsxTextElementData {
    /**
     * Whether a node was authored as explicit JSX (`<h1>`) or as implicitly
     * turned into JSX (`# hi`).
     *
     * Registered by `@mdx-js/mdx/lib/types.d.ts`.
     */
    _mdxExplicitJsx?: boolean | null | undefined
  }
}

declare module 'unified' {
  interface CompileResultMap {
    EstreeProgram: EstreeProgram
  }
}
