import Placeholder from '@tiptap/extension-placeholder';
import { EditorContent, useEditor, useEditorState } from '@tiptap/react';
import StarterKit from '@tiptap/starter-kit';
import React, { useEffect, useMemo } from 'react';
import { createPortal } from 'react-dom';

import { Button } from '../shared/ui/controls';

import styles from './EditorApp.module.css';
import { useEditorI18n } from './i18n/EditorI18nContext';
import { normalizeSceneDescriptionHtml } from './sceneDescriptionHtml';
import modalStyles from './SceneDescriptionModal.module.css';

type SceneDescriptionModalProps = {
  initialHtml: string;
  onClose: () => void;
  onSave: (html: string) => void;
};

function ToolbarIcon({ path, size = 14 }: { path: string; size?: number }) {
  return (
    <svg className={modalStyles.toolIcon} viewBox="0 0 24 24" width={size} height={size} aria-hidden>
      <path fill="currentColor" d={path} />
    </svg>
  );
}

function ToolButton({
  active = false,
  disabled = false,
  title,
  onClick,
  children,
}: {
  active?: boolean;
  disabled?: boolean;
  title: string;
  onClick: () => void;
  children: React.ReactNode;
}) {
  return (
    <button
      type="button"
      title={title}
      aria-label={title}
      aria-pressed={active}
      disabled={disabled}
      className={[modalStyles.toolBtn, active ? modalStyles.toolBtnActive : ''].filter(Boolean).join(' ')}
      onClick={onClick}
    >
      {children}
    </button>
  );
}

export function SceneDescriptionModal({ initialHtml, onClose, onSave }: SceneDescriptionModalProps) {
  const { t } = useEditorI18n();

  const extensions = useMemo(
    () => [
      StarterKit.configure({
        heading: { levels: [2, 3] },
        codeBlock: false,
        link: false,
      }),
      Placeholder.configure({
        placeholder: t('scene.descriptionPlaceholder'),
      }),
    ],
    [t],
  );

  const editor = useEditor({
    extensions,
    content: initialHtml || '',
    immediatelyRender: false,
    shouldRerenderOnTransaction: true,
    editorProps: {
      attributes: {
        class: [modalStyles.prose, 'tiptap'].join(' '),
        'aria-label': t('scene.descriptionModalTitle'),
      },
    },
  });

  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose();
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [onClose]);

  const toolbarState = useEditorState({
    editor,
    selector: ({ editor: ed }) => ({
      bold: Boolean(ed && !ed.isDestroyed && ed.isActive('bold')),
      italic: Boolean(ed && !ed.isDestroyed && ed.isActive('italic')),
      underline: Boolean(ed && !ed.isDestroyed && ed.isActive('underline')),
      bulletList: Boolean(ed && !ed.isDestroyed && ed.isActive('bulletList')),
      orderedList: Boolean(ed && !ed.isDestroyed && ed.isActive('orderedList')),
      h2: Boolean(ed && !ed.isDestroyed && ed.isActive('heading', { level: 2 })),
      h3: Boolean(ed && !ed.isDestroyed && ed.isActive('heading', { level: 3 })),
      blockquote: Boolean(ed && !ed.isDestroyed && ed.isActive('blockquote')),
    }),
  });

  const handleSave = () => {
    if (!editor || editor.isDestroyed) return;
    let raw = '';
    try {
      raw = editor.getHTML();
    } catch {
      return;
    }
    onSave(normalizeSceneDescriptionHtml(raw));
  };

  if (!editor || editor.isDestroyed) {
    return createPortal(
      <>
        <button
          type="button"
          aria-label={t('common.close')}
          onClick={onClose}
          className={styles.modalBackdrop}
        />
        <div role="dialog" aria-modal="true" className={[styles.modalDialog, modalStyles.dialog].join(' ')}>
          <div className={styles.modalHeader}>
            <div className={styles.modalTitle}>{t('scene.descriptionModalTitle')}</div>
            <button
              type="button"
              aria-label={t('common.close')}
              onClick={onClose}
              className={styles.modalClose}
            >
              ×
            </button>
          </div>
          <div className={modalStyles.editorShell} />
        </div>
      </>,
      document.body,
    );
  }

  return createPortal(
    <>
      <button
        type="button"
        aria-label={t('common.close')}
        onClick={onClose}
        className={styles.modalBackdrop}
      />
      <div role="dialog" aria-modal="true" className={[styles.modalDialog, modalStyles.dialog].join(' ')}>
        <div className={styles.modalHeader}>
          <div className={styles.modalTitle}>{t('scene.descriptionModalTitle')}</div>
          <button
            type="button"
            aria-label={t('common.close')}
            onClick={onClose}
            className={styles.modalClose}
          >
            ×
          </button>
        </div>

        <div className={modalStyles.editorShell}>
          <div className={modalStyles.toolbar} role="toolbar" aria-label={t('scene.descriptionToolbar')}>
            <div className={modalStyles.toolbarGroup}>
              <ToolButton
                title={t('scene.descriptionBold')}
                active={toolbarState?.bold ?? false}
                onClick={() => editor.chain().focus().toggleBold().run()}
              >
                <strong>B</strong>
              </ToolButton>
              <ToolButton
                title={t('scene.descriptionItalic')}
                active={toolbarState?.italic ?? false}
                onClick={() => editor.chain().focus().toggleItalic().run()}
              >
                <em>I</em>
              </ToolButton>
              <ToolButton
                title={t('scene.descriptionUnderline')}
                active={toolbarState?.underline ?? false}
                onClick={() => editor.chain().focus().toggleUnderline().run()}
              >
                <span style={{ textDecoration: 'underline' }}>U</span>
              </ToolButton>
            </div>
            <div className={modalStyles.toolbarSep} />
            <div className={modalStyles.toolbarGroup}>
              <ToolButton
                title={t('scene.descriptionHeading2')}
                active={toolbarState?.h2 ?? false}
                onClick={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}
              >
                H2
              </ToolButton>
              <ToolButton
                title={t('scene.descriptionHeading3')}
                active={toolbarState?.h3 ?? false}
                onClick={() => editor.chain().focus().toggleHeading({ level: 3 }).run()}
              >
                H3
              </ToolButton>
              <ToolButton
                title={t('scene.descriptionQuote')}
                active={toolbarState?.blockquote ?? false}
                onClick={() => editor.chain().focus().toggleBlockquote().run()}
              >
                <ToolbarIcon path="M6 17h3l2-4V7H5v6h3zm8 0h3l2-4V7h-6v6h3z" />
              </ToolButton>
            </div>
            <div className={modalStyles.toolbarSep} />
            <div className={modalStyles.toolbarGroup}>
              <ToolButton
                title={t('scene.descriptionBulletList')}
                active={toolbarState?.bulletList ?? false}
                onClick={() => editor.chain().focus().toggleBulletList().run()}
              >
                <ToolbarIcon path="M4 6h2v2H4V6zm0 5h2v2H4v-2zm0 5h2v2H4v-2zm4-10h12v2H8V6zm0 5h12v2H8v-2zm0 5h12v2H8v-2z" />
              </ToolButton>
              <ToolButton
                title={t('scene.descriptionOrderedList')}
                active={toolbarState?.orderedList ?? false}
                onClick={() => editor.chain().focus().toggleOrderedList().run()}
              >
                <ToolbarIcon path="M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1V14h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z" />
              </ToolButton>
            </div>
          </div>
          <div className={modalStyles.editorContent}>
            <EditorContent editor={editor} />
          </div>
        </div>

        <div className={styles.modalFooter}>
          <Button onClick={onClose}>{t('common.cancel')}</Button>
          <Button variant="primary" onClick={handleSave}>
            {t('common.save')}
          </Button>
        </div>
      </div>
    </>,
    document.body,
  );
}
