import React, { FormEventHandler, KeyboardEventHandler, useCallback, useState } from 'react';
import { isKeyHotkey } from 'is-hotkey';
import { Button, Line, Text, color, toRem } from 'folds';
import {
  CustomEditor,
  Toolbar,
  isEmptyEditor,
  resetEditor,
  resetEditorHistory,
  toMatrixCustomHTML,
  toPlainText,
  trimCustomHtml,
  useEditor,
} from '../../components/editor';
import { useMatrixClient } from '../../hooks/useMatrixClient';
import { sendForumReply, createForumReplyFromPayload } from './forumFeed';
import { FORUM_EDITOR_OUTPUT_OPTS } from './forumRichText';
import type { ForumPost } from './types';
import * as t from './forumTheme.css';

type ForumRichReplyComposerProps = {
  roomId: string;
  threadRootId: string;
  replyToEventId: string;
  onSent?: (reply: ForumPost) => void;
  onCancel?: () => void;
};

export function ForumRichReplyComposer({
  roomId,
  threadRootId,
  replyToEventId,
  onSent,
  onCancel,
}: ForumRichReplyComposerProps) {
  const mx = useMatrixClient();
  const editor = useEditor();
  const [sending, setSending] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const handleSubmit: FormEventHandler<HTMLFormElement> = useCallback(
    async (evt) => {
      evt.preventDefault();
      if (sending || isEmptyEditor(editor)) return;

      const plainText = toPlainText(editor.children, false).trim();
      const formattedHtml = trimCustomHtml(
        toMatrixCustomHTML(editor.children, FORUM_EDITOR_OUTPUT_OPTS)
      );
      if (!plainText) return;

      setSending(true);
      setError(null);
      try {
        const eventId = await sendForumReply(mx, roomId, threadRootId, replyToEventId, {
          plainText,
          formattedHtml,
        });
        resetEditor(editor);
        resetEditorHistory(editor);
        onSent?.(
          createForumReplyFromPayload(mx, roomId, eventId, replyToEventId, {
            plainText,
            formattedHtml,
          })
        );
      } catch (err) {
        setError(err instanceof Error ? err.message : 'Failed to send reply');
      } finally {
        setSending(false);
      }
    },
    [editor, mx, onSent, replyToEventId, roomId, sending, threadRootId]
  );

  const handleKeyDown: KeyboardEventHandler = useCallback(
    (evt) => {
      if (isKeyHotkey('mod+enter', evt) && !sending) {
        evt.preventDefault();
        evt.currentTarget.closest('form')?.requestSubmit();
      }
    },
    [sending]
  );

  return (
    <form className={t.ForumFeedReplyForm} onSubmit={handleSubmit}>
      <div className={t.ForumInlineReplyEditorWrap}>
        <CustomEditor
          editor={editor}
          placeholder="Write a reply…"
          maxHeight={toRem(240)}
          onKeyDown={handleKeyDown}
          bottom={
            <div>
              <Line variant="SurfaceVariant" size="300" />
              <Toolbar />
            </div>
          }
        />
      </div>
      {error && (
        <Text size="T200" style={{ color: color.Critical.Main }}>
          {error}
        </Text>
      )}
      <div className={t.ForumReplyFormActions}>
        {onCancel && (
          <Button type="button" variant="SurfaceVariant" size="300" onClick={onCancel} disabled={sending}>
            <Text size="B400">Cancel</Text>
          </Button>
        )}
        <Button type="submit" className={t.ForumReplySubmitBtn} variant="Primary" size="300" disabled={sending}>
          <Text size="B400">{sending ? 'Sending…' : 'Send reply'}</Text>
        </Button>
      </div>
    </form>
  );
}
