import { Mermaid, Playground, Code, Pre, Tabs } from 'nextra/components'
import { useRef, useCallback, useState, useEffect } from 'react'

export function Demo() {
  const [rawMdx, setRawMdx] = useState(`Playground components allow you to write Nextra compatible MDX that renders only on the client. It's modeled after the functionality found in [MDX Playground](https://mdxjs.com/playground).

In some instances where remote loading MDX is not an option, this may work as a great alternative.

Here's an example of a codeblock.

\`\`\`ts
console.log("Hello world, this is a playground component!");
\`\`\`

## Caveats

Due to the purely client-side nature of this component, features "Table of Contents" and "Frontmatter" will not work.

## Mermaid Example

\`\`\`mermaid
graph TD
subgraph AA [Consumers]
A[Mobile App]
B[Web App]
C[Node.js Client]
end
subgraph BB [Services]
E[REST API]
F[GraphQL API]
G[SOAP API]
end
Z[GraphQL API]
A --> Z
B --> Z
C --> Z
Z --> E
Z --> F
Z --> G
\`\`\``)
  const handleInput = useCallback(e => {
    setRawMdx(e.currentTarget.textContent ?? '')
  }, [])

  const spanRef = useRef(null)
  const initialRender = useRef(false)

  useEffect(() => {
    if (!initialRender.current) {
      initialRender.current = true
      spanRef.current.textContent = rawMdx
    }
  }, []);

  return (
    <div className="grid grid-cols-2 gap-2 mt-6">
      <Pre data-filename="MDX" icon={MdxIcon}>
        <Code>
          <span
            ref={spanRef}
            contentEditable
            suppressContentEditableWarning
            className="outline-none"
            onInput={handleInput}
          />
        </Code>
      </Pre>
      <div>
        <Playground
          fallback={
            <div className="flex h-full items-center justify-center text-4xl">
              Loading playground...
            </div>
          }
          source={rawMdx}
          components={{ Mermaid, $Tabs: Tabs }}
        />
      </div>
    </div>
  )
}

# Playground

<Demo />

## Usage

```mdx filename="Basic Usage"
import { Playground } from 'nextra/components'

# Playground

Below is a playground component. It mixes into the rest of your MDX perfectly.

<Playground source="## Hello world" />
```

You may also specify a fallback component like so:

```mdx filename="Usage with Fallback"
import { Playground } from 'nextra/components'

<Playground
  source="## Hello world"
  fallback={<div>Loading playground...</div>}
/>
```
