import React, { useState, useCallback } from 'react';
import { NeuraStream } from './NeuraStream';
import { CompletionsRequestOptions } from '../types';

interface Message {
  role: 'user' | 'assistant' | 'system';
  content: string;
}

interface NeuraChatProps {
  sessionId?: string;
  userId?: string;
  initialMessages?: Message[];
  reasoningFormat?: string;
  onNewMessage?: (message: Message) => void;
  renderMessage?: (message: Message, index: number) => React.ReactNode;
  renderInput?: (props: {
    value: string;
    onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
    onSubmit: () => void;
    disabled: boolean;
  }) => React.ReactNode;
}

export const NeuraChat: React.FC<NeuraChatProps> = ({
  sessionId,
  userId,
  initialMessages = [],
  reasoningFormat,
  onNewMessage,
  renderMessage,
  renderInput,
}) => {
  const [messages, setMessages] = useState<Message[]>(initialMessages);
  const [input, setInput] = useState('');
  const [isStreaming, setIsStreaming] = useState(false);

  const handleInputChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {
    setInput(e.target.value);
  }, []);

  const handleSubmit = useCallback(() => {
    if (!input.trim()) return;
    
    const userMessage: Message = { role: 'user', content: input };
    setMessages((prev) => [...prev, userMessage]);
    onNewMessage?.(userMessage);
    setInput('');
    setIsStreaming(true);
  }, [input, onNewMessage]);

  const handleStreamComplete = useCallback((content: string) => {
    const assistantMessage: Message = { role: 'assistant', content };
    setMessages((prev) => [...prev, assistantMessage]);
    onNewMessage?.(assistantMessage);
    setIsStreaming(false);
  }, [onNewMessage]);

  // Default message renderer
  const defaultRenderMessage = useCallback((message: Message, index: number) => (
    <div key={index} className={`message ${message.role}`}>
      <div className="message-role">{message.role}</div>
      <div className="message-content">{message.content}</div>
    </div>
  ), []);

  // Default input renderer
  const defaultRenderInput = useCallback(
    (props: {
      value: string;
      onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
      onSubmit: () => void;
      disabled: boolean;
    }) => (
      <div className="chat-input">
        <textarea
          value={props.value}
          onChange={props.onChange}
          disabled={props.disabled}
          placeholder="Type your message..."
          onKeyDown={(e) => {
            if (e.key === 'Enter' && !e.shiftKey) {
              e.preventDefault();
              props.onSubmit();
            }
          }}
        />
        <button onClick={props.onSubmit} disabled={props.disabled}>
          Send
        </button>
      </div>
    ),
    []
  );

  // Prepare the options for the stream
  const streamOptions: CompletionsRequestOptions = {
    messages: JSON.stringify(messages),
    sessionId,
    userId,
    stream: true,
    reasoningFormat,
  };

  return (
    <div className="neura-chat">
      <div className="chat-messages">
        {messages.map((message, index) => 
          (renderMessage || defaultRenderMessage)(message, index)
        )}
        
        {isStreaming && (
          <NeuraStream
            options={streamOptions}
            onComplete={handleStreamComplete}
          >
            {({ fullText, loading }) => (
              loading ? (
                <div className="message assistant">
                  <div className="message-role">assistant</div>
                  <div className="message-content">{fullText || 'Thinking...'}</div>
                </div>
              ) : null
            )}
          </NeuraStream>
        )}
      </div>
      
      {(renderInput || defaultRenderInput)({
        value: input,
        onChange: handleInputChange,
        onSubmit: handleSubmit,
        disabled: isStreaming,
      })}
    </div>
  );
};