import { defineStory } from '@djangocfg/playground';
import { MarkdownEditor } from './MarkdownEditor';
import { mentionPresets } from './mentionPresets';
import { useState, type ReactNode } from 'react';
import type { MentionConfig, MentionMarkdownRenderer } from './types';

export default defineStory({
  title: 'Tools/Markdown Editor',
  component: MarkdownEditor,
  description: 'WYSIWYG markdown editor with Tiptap. Supports headings, lists, mentions, and more.',
});

const SAMPLE_MARKDOWN = `# Character Bio

**Type:** Maltipoo (apricot coat)
**Age:** 3 years

## Visual Design

Medium-small Maltipoo, compact and agile.

- Sharp, intelligent eyes (dark brown)
- Simple collar (hides micro-gear)
- Expressions shift quickly

## Personality

> Pixar Note: Her face must carry duality.

1. Emotionally guarded
2. Independent and decisive
3. Dry sense of humor
`;

const MENTION_ITEMS: MentionConfig = {
  items: [
    { id: '1', label: 'Alice', description: 'Protagonist', thumbnail: 'https://i.pravatar.cc/48?u=alice' },
    { id: '2', label: 'Bob', description: 'Antagonist', thumbnail: 'https://i.pravatar.cc/48?u=bob' },
    { id: '3', label: 'Charlie', description: 'Side character', thumbnail: 'https://i.pravatar.cc/48?u=charlie' },
    { id: '4', label: 'Diana', description: 'Narrator' },
    { id: '5', label: 'Eve', description: 'Mystery character' },
  ],
};

export function Default() {
  const [value, setValue] = useState(SAMPLE_MARKDOWN);
  return (
    <div style={{ maxWidth: 700 }}>
      <MarkdownEditor value={value} onChange={setValue} />
      <RawPreview value={value} />
    </div>
  );
}

export function WithMentions() {
  const [value, setValue] = useState('Hello @Alice! This scene features @Bob too.\n\nType @ to mention characters.');
  const [ids, setIds] = useState<string[]>([]);

  return (
    <div style={{ maxWidth: 700 }}>
      <MarkdownEditor
        value={value}
        onChange={setValue}
        mentions={MENTION_ITEMS}
        onMentionIdsChange={setIds}
        placeholder="Describe the scene... Use @ to mention characters"
      />
      {ids.length > 0 && (
        <div style={{ marginTop: 8, fontSize: 12, opacity: 0.6 }}>
          Mentioned IDs: {ids.join(', ')}
        </div>
      )}
      <RawPreview value={value} />
    </div>
  );
}

export function Empty() {
  const [value, setValue] = useState('');
  return (
    <div style={{ maxWidth: 600 }}>
      <MarkdownEditor value={value} onChange={setValue} placeholder="Start writing..." />
    </div>
  );
}

export function Disabled() {
  return (
    <div style={{ maxWidth: 600 }}>
      <MarkdownEditor value="This editor is **read-only**." onChange={() => {}} disabled />
    </div>
  );
}

export function NoToolbar() {
  const [value, setValue] = useState('Plain text without toolbar.\n\nStill supports **markdown** shortcuts.');
  return (
    <div style={{ maxWidth: 600 }}>
      <MarkdownEditor value={value} onChange={setValue} showToolbar={false} />
    </div>
  );
}

export function Compact() {
  const [value, setValue] = useState('Short note');
  return (
    <div style={{ maxWidth: 400 }}>
      <MarkdownEditor value={value} onChange={setValue} minHeight={60} placeholder="Quick note..." />
    </div>
  );
}

export function WithCustomUriPreset() {
  const [value, setValue] = useState(
    'Reference @Alice and @Bob — markdown will carry machine-readable URIs.\n\nType @ to add more.',
  );

  return (
    <SerializationDemo
      description={
        <>
          <code>mentionPresets.customUri('myapp', 'user')</code> — emits
          <code>{' @[Label](myapp://user/id)'}</code>. Useful when downstream
          parses the markdown back into deep-links while keeping the visible
          <code>@</code> handle.
        </>
      }
      value={value}
      onChange={setValue}
      renderMarkdown={mentionPresets.customUri('myapp', 'user')}
    />
  );
}

export function WithMarkdownLinkPreset() {
  const [value, setValue] = useState('Ping @Alice when ready, cc @Charlie.');

  return (
    <SerializationDemo
      description={
        <>
          <code>mentionPresets.markdownLink('https://example.com/u/')</code> —
          serializes mentions as ordinary clickable links: <code>[@Label](https://example.com/u/id)</code>.
        </>
      }
      value={value}
      onChange={setValue}
      renderMarkdown={mentionPresets.markdownLink('https://example.com/u/')}
    />
  );
}

export function WithCustomRenderer() {
  const [value, setValue] = useState('Tag @Alice and @Bob to assign the task.');

  // Hand-rolled serializer — any (attrs) => string works.
  const renderMarkdown: MentionMarkdownRenderer = ({ id, label }) =>
    `{{user:${id}|${label || 'unknown'}}}`;

  return (
    <SerializationDemo
      description={
        <>
          Inline custom renderer: <code>{`({ id, label }) => \`{{user:\${id}|\${label}}}\``}</code>.
          Shows that the serializer is just a function — you control the wire format.
        </>
      }
      value={value}
      onChange={setValue}
      renderMarkdown={renderMarkdown}
    />
  );
}

interface SerializationDemoProps {
  description: ReactNode;
  value: string;
  onChange: (v: string) => void;
  renderMarkdown: MentionMarkdownRenderer;
}

function SerializationDemo({ description, value, onChange, renderMarkdown }: SerializationDemoProps) {
  const mentions: MentionConfig = { ...MENTION_ITEMS, renderMarkdown };

  return (
    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16, maxWidth: 900 }}>
      <div>
        <p style={{ fontSize: 12, opacity: 0.7, marginBottom: 8 }}>{description}</p>
        <MarkdownEditor
          value={value}
          onChange={onChange}
          mentions={mentions}
          placeholder="Type @ to insert a mention..."
        />
      </div>
      <div>
        <div style={{ fontSize: 11, opacity: 0.5, marginBottom: 4, textTransform: 'uppercase', letterSpacing: 0.5 }}>
          Serialized markdown
        </div>
        <pre
          style={{
            fontSize: 12,
            padding: 12,
            background: 'rgba(127,127,127,0.08)',
            borderRadius: 6,
            whiteSpace: 'pre-wrap',
            wordBreak: 'break-word',
            margin: 0,
          }}
        >
          {value || '(empty)'}
        </pre>
      </div>
    </div>
  );
}

function RawPreview({ value }: { value: string }) {
  return (
    <details style={{ marginTop: 16 }}>
      <summary style={{ cursor: 'pointer', opacity: 0.5, fontSize: 12 }}>Raw markdown</summary>
      <pre style={{ fontSize: 11, opacity: 0.6, whiteSpace: 'pre-wrap', marginTop: 8 }}>{value}</pre>
    </details>
  );
}
