'use client';

/**
 * Chat input using the production-ready TipTap IMEditor.
 * Supports @mentions, file uploads, emoji picker, and rich message AST.
 */

import { forwardRef, useImperativeHandle, useMemo, useRef } from 'react';
import { IMEditor } from './editor/IMEditor';
import { useRoom } from '@/contexts';
import type { MessageAST } from './editor/types';
import type { IMEditorHandle } from './editor/IMEditor';

export interface MessageInputProps {
  roomName: string;
  onSend: (content: string, attachmentIds?: string[]) => void;
  replyingTo?: { id: string; display_name?: string; content: string } | null;
  onCancelReply?: () => void;
}

export interface MessageInputHandle {
  focus: () => void;
  clearContent: () => void;
  getContent: () => string;
  insertMention: (type: string, id: string, label: string) => void;
  getAttachmentIds: () => string[];
}

export const MessageInput = forwardRef<MessageInputHandle, MessageInputProps>(function MessageInput(
  { roomName, onSend, replyingTo, onCancelReply },
  ref,
) {
  const { members, activeRoomId } = useRoom();

  // Ref passed to the inner IMEditor
  const innerEditorRef = useRef<IMEditorHandle | null>(null);

  // Expose a subset of IMEditorHandle (plus getAttachmentIds) as MessageInputHandle
  useImperativeHandle(ref, () => ({
    focus: () => innerEditorRef.current?.focus(),
    clearContent: () => innerEditorRef.current?.clearContent(),
    getContent: () => innerEditorRef.current?.getContent() ?? '',
    insertMention: (type: string, id: string, label: string) =>
      innerEditorRef.current?.insertMention(type, id, label),
    getAttachmentIds: () => innerEditorRef.current?.getAttachmentIds() ?? [],
  }), []);

  // Slash commands available in the editor
  const SLASH_COMMANDS = [
    { id: 'ai', label: '/ai', description: 'Ask AI a question', type: 'command' as const },
    { id: 'remind', label: '/remind', description: 'Set a reminder (e.g. /remind 10m Check CI)', type: 'command' as const },
    { id: 'poll', label: '/poll', description: 'Create a poll (e.g. /poll "Question?" A B C)', type: 'command' as const },
    { id: 'code-review', label: '/code-review', description: 'Request AI code review', type: 'command' as const },
  ];

  // Special mention items — @here (online), @channel (all members)
  const SPECIAL_MENTIONS = [
    {
      id: '__here__',
      label: 'here',
      description: 'Notify online members',
      type: 'special_here' as const,
    },
    {
      id: '__channel__',
      label: 'channel',
      description: 'Notify all members',
      type: 'special_channel' as const,
    },
  ];

  // Transform room data into MentionItems — memoized to prevent IMEditor re-creation
  const mentionItems = useMemo(() => ({
    users: members.map((m) => ({
      id: m.user,
      label: m.user_info?.username ?? m.user,
      type: 'user' as const,
      avatar: m.user_info?.avatar_url ?? undefined,
    })),
    channels: [] as { id: string; label: string; type: 'channel'; avatar?: string }[],
    ai: [] as { id: string; label: string; type: 'ai'; avatar?: string }[],
    commands: SLASH_COMMANDS,
    specialMentions: SPECIAL_MENTIONS,
  }), [members]);

  // File upload handler — POST to /rooms/{room_id}/upload
  const handleUploadFile = async (file: File): Promise<{ id: string; url: string }> => {
    if (!activeRoomId) throw new Error('No active room');
    const formData = new FormData();
    formData.append('file', file);
    const baseUrl = import.meta.env.VITE_API_BASE_URL ?? window.location.origin;
    const res = await fetch(`${baseUrl}/rooms/${activeRoomId}/upload`, { method: 'POST', body: formData });
    if (!res.ok) throw new Error('Upload failed');
    return res.json();
  };

  // onSend: extract plain text from MessageAST for sending
  const handleSend = (text: string, _ast: MessageAST) => {
    onSend(text);
  };

  return (
    <IMEditor
      ref={innerEditorRef}
      replyingTo={replyingTo}
      onCancelReply={onCancelReply}
      onSend={handleSend}
      mentionItems={mentionItems}
      onUploadFile={handleUploadFile}
      placeholder={`Message #${roomName}`}
    />
  );
});
