import React, { useState, useCallback, useMemo } from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
import uuid from 'uuid/v1';
import { sendMessage, selectSendStatus, selectSendError, clearSendError } from '../../../store/features/sessionChatSlice';
import { selectSessionId } from '../../../store/features/activeSessionSlice';
import { useJamServerContext } from '../../../context/JamServerContext';
import { useAuth } from '../../../context/UserAuth';

/**
 * JKChatComposer - Message composition component
 *
 * Features:
 * - Controlled textarea for message input
 * - Character count display (X/255) with color-coded feedback
 * - Validation: 1-255 characters after trim
 * - Keyboard handling: Enter to send, Shift+Enter for newline
 * - Disabled states: disconnected, sending, invalid input
 * - Error display for send failures
 * - Disconnected warning
 *
 * Validation levels:
 * - Gray: 0-230 characters (normal)
 * - Yellow: 231-255 characters (approaching limit)
 * - Red: 256+ characters (over limit)
 *
 * @param {Object} props - Component props
 * @param {React.Ref} props.textareaRef - Ref for textarea (for focus management)
 */
const JKChatComposer = ({ textareaRef }) => {
  const dispatch = useDispatch();
  const [inputText, setInputText] = useState('');

  // Redux selectors
  const sessionId = useSelector(selectSessionId);
  const sendStatus = useSelector(selectSendStatus);
  const sendError = useSelector(selectSendError);

  // WebSocket connection status and client ID
  const { isConnected, server } = useJamServerContext();

  // Current user for optimistic updates
  const { currentUser } = useAuth();

  // Validation and state calculations
  const trimmedText = useMemo(() => inputText.trim(), [inputText]);
  const charCount = inputText.length;
  const isOverLimit = charCount > 255;
  const isNearLimit = charCount > 230 && charCount <= 255; // 90% threshold
  const isValid = trimmedText.length > 0 && trimmedText.length <= 255;
  const isSending = sendStatus === 'loading';
  const canSend = isValid && isConnected && !isSending;

  // Character count color
  const countColor = isOverLimit ? '#dc3545' : isNearLimit ? '#ffc107' : '#6c757d';

  // Validation message
  const getValidationMessage = useCallback(() => {
    if (isOverLimit) {
      return `Message is ${charCount - 255} characters too long`;
    }
    if (!isConnected) {
      return 'Waiting for connection...';
    }
    if (trimmedText.length === 0 && charCount > 0) {
      return 'Message cannot be empty';
    }
    return null;
  }, [isOverLimit, charCount, isConnected, trimmedText.length]);

  const validationMessage = getValidationMessage();

  // Event handlers
  const handleInputChange = useCallback(e => {
    setInputText(e.target.value);
  }, []);

  const handleSend = useCallback(async () => {
    if (!canSend || !currentUser) return;

    // Send message via Redux thunk with optimistic update parameters
    await dispatch(
      sendMessage({
        channel: sessionId,
        sessionId,
        message: trimmedText,
        optimisticId: uuid(),
        userId: currentUser.id,
        userName: currentUser.name,
        clientId: server?.clientId
      })
    );

    // Clear input on success
    setInputText('');
  }, [canSend, dispatch, sessionId, trimmedText, currentUser, server?.clientId]);

  const handleKeyDown = useCallback(
    e => {
      // Enter without Shift: send message
      if (e.key === 'Enter' && !e.shiftKey) {
        e.preventDefault(); // Prevent newline insertion
        handleSend();
      }
      // Shift+Enter: allow default (insert newline)
    },
    [handleSend]
  );

  const handleRetry = useCallback(() => {
    dispatch(clearSendError());
  }, [dispatch]);

  return (
    <div style={{ padding: '12px', borderTop: '1px solid #ddd' }}>
      {/* Textarea */}
      <textarea
        ref={textareaRef}
        value={inputText}
        onChange={handleInputChange}
        onKeyDown={handleKeyDown}
        placeholder="Type a message..."
        rows={3}
        aria-label="Type your message"
        aria-describedby="char-count"
        aria-invalid={isOverLimit}
        style={{
          width: '100%',
          padding: '8px',
          border: '1px solid #ccc',
          borderRadius: '4px',
          resize: 'none',
          fontFamily: 'inherit',
          fontSize: '14px',
          boxSizing: 'border-box'
        }}
        disabled={!isConnected || isSending}
      />

      {/* Character count and send button row */}
      <div
        style={{
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          marginTop: '8px'
        }}
      >
        {/* Character count with validation message */}
        <div style={{ display: 'flex', flexDirection: 'column', flex: 1 }}>
          <span
            id="char-count"
            style={{
              fontSize: '12px',
              color: countColor,
              fontWeight: isOverLimit || isNearLimit ? 'bold' : 'normal'
            }}
          >
            {charCount}/255
          </span>
          {validationMessage && (
            <div
              role="alert"
              aria-live="polite"
              aria-atomic="true"
              style={{
                fontSize: '11px',
                color: isOverLimit ? '#dc3545' : '#ffc107',
                marginTop: '2px'
              }}
            >
              {validationMessage}
            </div>
          )}
        </div>

        {/* Send button */}
        <button
          onClick={handleSend}
          disabled={!canSend}
          style={{
            padding: '6px 16px',
            backgroundColor: canSend ? '#007bff' : '#ccc',
            color: 'white',
            border: 'none',
            borderRadius: '4px',
            cursor: canSend ? 'pointer' : 'not-allowed',
            fontSize: '14px',
            fontWeight: '500'
          }}
        >
          {isSending ? 'Sending...' : 'Send'}
        </button>
      </div>

      {/* Error display with retry button */}
      {sendError && (
        <div
          style={{
            marginTop: '8px',
            padding: '8px',
            backgroundColor: '#dc3545',
            color: 'white',
            borderRadius: '4px',
            fontSize: '12px',
            display: 'flex',
            justifyContent: 'space-between',
            alignItems: 'center'
          }}
        >
          <span>Failed to send message. Please try again.</span>
          <button
            onClick={handleRetry}
            style={{
              marginLeft: '8px',
              padding: '4px 8px',
              backgroundColor: 'white',
              color: '#dc3545',
              border: 'none',
              borderRadius: '3px',
              cursor: 'pointer',
              fontSize: '11px',
              fontWeight: 'bold'
            }}
          >
            Retry
          </button>
        </div>
      )}
    </div>
  );
};

JKChatComposer.propTypes = {
  textareaRef: PropTypes.object
};

JKChatComposer.defaultProps = {
  textareaRef: null
};

export default React.memo(JKChatComposer);
