/**
 * MessageInputEnhanced Component
 *
 * Full-featured message input with rainbow animations, empty state,
 * image upload, file upload, and sophisticated send button states.
 *
 * Features:
 * - Rainbow border/shadow animation when focused, streaming, or chat empty
 * - Empty state intro (rainbow "co" + welcome text) when no messages
 * - Image upload with preview and remove functionality
 * - File upload support (optional, via onFileUpload prop)
 * - Absolute positioned buttons (file, image, send) overlaying input
 * - Arrow-up send icon with ActivityIndicator when sending
 * - Dynamic send button styling (white/black based on content + theme)
 * - Focus state management with callbacks
 * - Safe area support for proper bottom padding
 *
 * This component achieves 100% feature parity with the original input
 * while maintaining clean, modular, testable code.
 */

import React, { useState, useCallback, useRef } from 'react';
import {
  View,
  Text,
  TextInput,
  TouchableOpacity,
  StyleSheet,
  Platform,
  Image,
  Alert,
  Animated,
  ActivityIndicator,
} from 'react-native';
import { Ionicons } from '@expo/vector-icons';
import * as ImagePicker from 'expo-image-picker';
import { useSafeAreaInsets } from 'react-native-safe-area-context';

import { useRainbowAnimation, RAINBOW_COLORS } from '../hooks/useRainbowAnimation';
import EmptyStateIntro from './EmptyStateIntro';
import { pickFile } from '../utils/fileUpload';
import type { Theme } from '../theme';

interface MessageInputEnhancedProps {
  onSend: (text: string) => void;
  isSendingMessage: boolean;
  theme: Theme;
  colorScheme: 'light' | 'dark';

  // Empty state
  hasMessages: boolean;
  isLoadingMessages?: boolean;

  // Rainbow animation triggers
  isStreaming: boolean;
  hasExpandedReasoning: boolean;

  // Image management (external state)
  selectedImages: Array<{ uri: string; base64: string; mediaType: string }>;
  onAddImage: (image: { uri: string; base64: string; mediaType: string }) => void;
  onRemoveImage: (index: number) => void;

  // Optional file upload handler
  onFileUpload?: (file: File) => Promise<void>;

  // Optional callbacks
  onFocusChange?: (focused: boolean) => void;
  disabled?: boolean;
}

export const MessageInputEnhanced: React.FC<MessageInputEnhancedProps> = ({
  onSend,
  isSendingMessage,
  theme,
  colorScheme,
  hasMessages,
  isLoadingMessages = false,
  isStreaming,
  hasExpandedReasoning,
  selectedImages,
  onAddImage,
  onRemoveImage,
  onFileUpload,
  onFocusChange,
  disabled = false,
}) => {
  const insets = useSafeAreaInsets();
  const inputRef = useRef<TextInput>(null);

  // State
  const [inputText, setInputText] = useState('');
  const [isInputFocused, setIsInputFocused] = useState(false);
  const [isUploadingFile, setIsUploadingFile] = useState(false);

  // Rainbow animation
  const { rainbowAnimValue } = useRainbowAnimation({
    isStreaming,
    isInputFocused,
    hasExpandedReasoning,
    hasMessages,
  });

  // Computed values
  const hasContent = inputText.trim().length > 0 || selectedImages.length > 0;
  const isDark = colorScheme === 'dark';

  // Image picker
  const handlePickImage = async () => {
    try {
      const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
      if (status !== 'granted') {
        Alert.alert('Permission Required', 'Please allow access to your photo library.');
        return;
      }

      const result = await ImagePicker.launchImageLibraryAsync({
        mediaTypes: ['images'],
        allowsMultipleSelection: false,
        quality: 0.8,
        base64: true,
      });

      if (!result.canceled && result.assets && result.assets.length > 0) {
        const asset = result.assets[0];
        if (asset.base64) {
          // Check size: 5MB limit
          const MAX_SIZE = 5 * 1024 * 1024;
          if (asset.base64.length > MAX_SIZE) {
            const sizeMB = (asset.base64.length / 1024 / 1024).toFixed(2);
            Alert.alert('Image Too Large', `This image is ${sizeMB}MB. Maximum allowed is 5MB.`);
            return;
          }

          const mediaType =
            asset.uri.match(/\.(jpg|jpeg)$/i)
              ? 'image/jpeg'
              : asset.uri.match(/\.png$/i)
              ? 'image/png'
              : asset.uri.match(/\.gif$/i)
              ? 'image/gif'
              : asset.uri.match(/\.webp$/i)
              ? 'image/webp'
              : 'image/jpeg';

          onAddImage({
            uri: asset.uri,
            base64: asset.base64,
            mediaType,
          });
        }
      }
    } catch (error) {
      console.error('Error picking image:', error);
      Alert.alert('Error', 'Failed to pick image');
    }
  };

  // File picker
  const handlePickFile = async () => {
    if (!onFileUpload) {
      Alert.alert('Not Available', 'File upload is not yet configured.');
      return;
    }

    try {
      setIsUploadingFile(true);
      const result = await pickFile();

      if (result) {
        await onFileUpload(result.file);
      }
    } catch (error: any) {
      console.error('File upload error:', error);
      Alert.alert('Upload Failed', error.message || 'Failed to upload file');
    } finally {
      setIsUploadingFile(false);
    }
  };

  // Send message
  const handleSend = useCallback(() => {
    if (hasContent && !disabled && !isSendingMessage) {
      onSend(inputText.trim());
      setInputText('');
      inputRef.current?.clear();
    }
  }, [inputText, hasContent, disabled, isSendingMessage, onSend]);

  // Focus handlers
  const handleFocus = useCallback(() => {
    setIsInputFocused(true);
    onFocusChange?.(true);
  }, [onFocusChange]);

  const handleBlur = useCallback(() => {
    setIsInputFocused(false);
    onFocusChange?.(false);
  }, [onFocusChange]);

  // Input wrapper style (base + rainbow when focused)
  const inputWrapperStyle = {
    borderRadius: 24,
    borderWidth: 2,
    borderColor: isDark ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.1)',
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 8,
    elevation: 2,
  };

  // Send button style (white/black based on content, transparent when empty)
  const sendButtonStyle = {
    backgroundColor:
      !hasContent || isSendingMessage ? 'transparent' : isDark ? '#FFFFFF' : '#000000',
  };

  // Send icon color (inverted from button background)
  const sendIconColor = !hasContent ? '#444444' : isDark ? '#000000' : '#FFFFFF';

  return (
    <View
      style={[
        styles.inputContainer,
        {
          paddingBottom: Math.max(insets.bottom, 16),
        },
        !hasMessages && styles.inputContainerCentered,
      ]}
    >
      <View style={styles.inputCentered}>
        {/* Loading state - shown while messages are loading */}
        {isLoadingMessages && (
          <View style={styles.loadingContainer}>
            <ActivityIndicator size="large" color={theme.colors.interactive.primary} />
            <Text style={[styles.loadingText, { color: theme.colors.text.secondary }]}>
              Loading messages...
            </Text>
          </View>
        )}

        {/* Empty state intro - shown above input when chat is empty (but not loading) */}
        {!hasMessages && !isLoadingMessages && <EmptyStateIntro theme={theme} />}

        {/* Image preview section */}
        {selectedImages.length > 0 && (
          <View style={styles.imagePreviewContainer}>
            {selectedImages.map((img, index) => (
              <View key={index} style={styles.imagePreviewWrapper}>
                <Image source={{ uri: img.uri }} style={styles.imagePreview} />
                <TouchableOpacity
                  onPress={() => onRemoveImage(index)}
                  style={styles.removeImageButton}
                >
                  <Ionicons name="close-circle" size={24} color="#fff" />
                </TouchableOpacity>
              </View>
            ))}
          </View>
        )}

        {/* Input wrapper with rainbow border/shadow when focused */}
        <Animated.View
          style={[
            styles.inputWrapper,
            inputWrapperStyle,
            isInputFocused && {
              borderColor: rainbowAnimValue.interpolate({
                inputRange: [0, 0.2, 0.4, 0.6, 0.8, 1],
                outputRange: RAINBOW_COLORS,
              }),
              shadowColor: rainbowAnimValue.interpolate({
                inputRange: [0, 0.2, 0.4, 0.6, 0.8, 1],
                outputRange: RAINBOW_COLORS,
              }),
              shadowOpacity: 0.4,
              shadowRadius: 16,
            },
          ]}
        >
          {/* File button (absolute positioned) */}
          {onFileUpload && (
            <TouchableOpacity
              onPress={handlePickFile}
              style={styles.fileButton}
              disabled={disabled || isSendingMessage || isUploadingFile}
            >
              {isUploadingFile ? (
                <ActivityIndicator size="small" color="#666666" />
              ) : (
                <Ionicons
                  name="attach-outline"
                  size={20}
                  color={disabled ? '#333333' : '#666666'}
                />
              )}
            </TouchableOpacity>
          )}

          {/* Image button (absolute positioned) */}
          <TouchableOpacity
            onPress={handlePickImage}
            style={[styles.imageButton, !onFileUpload && styles.imageButtonNoFile]}
            disabled={disabled || isSendingMessage}
          >
            <Ionicons
              name="image-outline"
              size={20}
              color={disabled ? '#333333' : '#666666'}
            />
          </TouchableOpacity>

          {/* Text input (full width) */}
          <TextInput
            ref={inputRef}
            style={[
              styles.textInput,
              {
                color: theme.colors.text.primary,
                backgroundColor: isDark ? '#242424' : '#FFFFFF',
              },
            ]}
            placeholder="What's on your mind?"
            placeholderTextColor={theme.colors.text.tertiary}
            value={inputText}
            onChangeText={setInputText}
            onFocus={handleFocus}
            onBlur={handleBlur}
            multiline
            maxLength={15000}
            editable={!disabled && !isSendingMessage}
            onSubmitEditing={handleSend}
          />

          {/* Send button (absolute positioned) */}
          <TouchableOpacity
            onPress={handleSend}
            style={[styles.sendButton, sendButtonStyle]}
            disabled={disabled || !hasContent || isSendingMessage}
          >
            {isSendingMessage ? (
              <ActivityIndicator size="small" color={isDark ? '#fff' : '#000'} />
            ) : (
              <Ionicons name="arrow-up" size={20} color={sendIconColor} />
            )}
          </TouchableOpacity>
        </Animated.View>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  inputContainer: {
    width: '100%',
    paddingHorizontal: 18,
    alignItems: 'center',
  },
  inputContainerCentered: {
    justifyContent: 'center',
  },
  inputCentered: {
    position: 'relative',
    maxWidth: 700,
    width: '100%',
  },
  loadingContainer: {
    alignItems: 'center',
    justifyContent: 'center',
    paddingVertical: 40,
  },
  loadingText: {
    marginTop: 16,
    fontSize: 14,
    fontFamily: 'Lexend_400Regular',
  },
  imagePreviewContainer: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    marginBottom: 12,
  },
  imagePreviewWrapper: {
    marginRight: 8,
    marginBottom: 8,
    position: 'relative',
  },
  imagePreview: {
    width: 80,
    height: 80,
    borderRadius: 8,
  },
  removeImageButton: {
    position: 'absolute',
    top: -8,
    right: -8,
    backgroundColor: 'rgba(0, 0, 0, 0.6)',
    borderRadius: 12,
  },
  inputWrapper: {
    position: 'relative',
    flexDirection: 'row',
    alignItems: 'flex-end',
  },
  fileButton: {
    position: 'absolute',
    right: 88,
    bottom: 8,
    width: 32,
    height: 32,
    borderRadius: 16,
    justifyContent: 'center',
    alignItems: 'center',
    zIndex: 1,
  },
  imageButton: {
    position: 'absolute',
    right: 52,
    bottom: 8,
    width: 32,
    height: 32,
    borderRadius: 16,
    justifyContent: 'center',
    alignItems: 'center',
    zIndex: 1,
  },
  imageButtonNoFile: {
    right: 88, // Move to file button position when no file upload
  },
  textInput: {
    width: '100%',
    minHeight: 40,
    maxHeight: 120,
    paddingLeft: 18,
    paddingRight: 130, // Space for buttons
    paddingTop: 8,
    paddingBottom: 8,
    borderRadius: 24,
    fontSize: 16,
    lineHeight: 24,
    borderWidth: 0,
    fontFamily: 'Lexend_400Regular',
    ...Platform.select({
      web: {
        // @ts-ignore - web-only properties
        outline: 'none',
        outlineStyle: 'none',
        WebkitAppearance: 'none',
        MozAppearance: 'none',
        resize: 'none',
        overflowY: 'auto',
      },
    }),
  },
  sendButton: {
    position: 'absolute',
    right: 10,
    bottom: 8,
    width: 32,
    height: 32,
    borderRadius: 16,
    justifyContent: 'center',
    alignItems: 'center',
  },
});

export default MessageInputEnhanced;
