import { useState, useRef } from 'react';
import {
  View,
  Text,
  TextInput,
  TouchableOpacity,
  StyleSheet,
  ActivityIndicator,
  Platform,
  Alert,
} from 'react-native';
import { Image } from 'expo-image';
import * as ImagePicker from 'expo-image-picker';
// TODO(sdk54): migrate to new expo-file-system class-based API (File/Directory/Paths) — see Task #14
import * as FileSystem from 'expo-file-system/legacy';
import { Ionicons } from '@expo/vector-icons';
import { useTranslation } from 'react-i18next';
import { supabase } from '../../lib/supabase';
import { useColors } from '../../lib/theme';

type ReplyTo = { id: string; nickname: string; content: string };

export type SendPayload = {
  content: string;
  replyToId?: string;
  attachmentUrl?: string;
  attachmentType?: string;
  attachmentName?: string;
};

type Props = {
  replyTo: ReplyTo | null;
  sending?: boolean;
  placeholder?: string;
  disabled?: boolean;
  onSend: (data: SendPayload) => void;
  onCancelReply: () => void;
};

export function ChatInput({
  replyTo,
  sending,
  placeholder,
  disabled,
  onSend,
  onCancelReply,
}: Props) {
  const { t } = useTranslation();
  const colors = useColors();
  const [text, setText] = useState('');
  const [attachment, setAttachment] = useState<{
    uri: string;
    name: string;
    isImage: boolean;
  } | null>(null);
  const [uploading, setUploading] = useState(false);
  const inputRef = useRef<TextInput>(null);

  const hasContent = text.trim().length > 0 || attachment !== null;

  async function pickImage() {
    const perm = await ImagePicker.requestMediaLibraryPermissionsAsync();
    if (!perm.granted) {
      Alert.alert('Foto-Zugriff', 'Bitte Foto-Zugriff in den Einstellungen erlauben.');
      return;
    }
    const result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      quality: 0.8,
    });
    if (!result.canceled && result.assets[0]?.uri) {
      const a = result.assets[0];
      setAttachment({
        uri: a.uri,
        name: a.fileName ?? `image-${Date.now()}.jpg`,
        isImage: true,
      });
    }
  }

  function clearAttachment() {
    setAttachment(null);
  }

  async function uploadAttachment(): Promise<{
    url: string;
    type: string;
    name: string;
  } | null> {
    if (!attachment) return null;
    try {
      setUploading(true);
      const ext = attachment.name.split('.').pop() || 'jpg';
      const path = `chat/${Date.now()}_${Math.random().toString(36).slice(2, 8)}.${ext}`;
      const base64 = await FileSystem.readAsStringAsync(attachment.uri, {
        encoding: FileSystem.EncodingType.Base64,
      });
      const arrayBuffer = decodeBase64(base64);
      const { error } = await supabase.storage
        .from('chat-attachments')
        .upload(path, arrayBuffer, {
          cacheControl: '3600',
          upsert: false,
          contentType: attachment.isImage ? 'image/jpeg' : 'application/octet-stream',
        });
      if (error) throw error;
      const { data } = supabase.storage.from('chat-attachments').getPublicUrl(path);
      return {
        url: data.publicUrl,
        type: attachment.isImage ? 'image' : 'file',
        name: attachment.name,
      };
    } catch (err: any) {
      Alert.alert(t('chat.upload_failed'), err?.message ?? '');
      return null;
    } finally {
      setUploading(false);
    }
  }

  async function handleSend() {
    const content = text.trim();
    if (!content && !attachment) return;

    let attachmentMeta: { url: string; type: string; name: string } | null = null;
    if (attachment) {
      attachmentMeta = await uploadAttachment();
      if (!attachmentMeta) return;
    }

    onSend({
      content,
      replyToId: replyTo?.id,
      attachmentUrl: attachmentMeta?.url,
      attachmentType: attachmentMeta?.type,
      attachmentName: attachmentMeta?.name,
    });
    setText('');
    setAttachment(null);
  }

  const styles = makeStyles(colors);

  return (
    <View style={styles.container}>
      {/* Reply preview */}
      {replyTo && (
        <View style={styles.replyBar}>
          <Ionicons name="arrow-undo" size={14} color="#007AFF" style={{ marginRight: 6 }} />
          <View style={{ flex: 1 }}>
            <Text style={styles.replyName} numberOfLines={1}>
              {t('chat.reply_to')} {replyTo.nickname}
            </Text>
            <Text style={styles.replyContent} numberOfLines={1}>
              {replyTo.content || '…'}
            </Text>
          </View>
          <TouchableOpacity hitSlop={10} onPress={onCancelReply} activeOpacity={0.7}>
            <Ionicons name="close" size={16} color="#737373" />
          </TouchableOpacity>
        </View>
      )}

      {/* Attachment preview */}
      {attachment && (
        <View style={styles.attachBar}>
          {attachment.isImage ? (
            <Image source={{ uri: attachment.uri }} style={styles.attachImg} contentFit="cover" />
          ) : (
            <View style={styles.attachFileIcon}>
              <Ionicons name="document" size={18} color="#737373" />
            </View>
          )}
          <Text style={styles.attachName} numberOfLines={1}>
            {attachment.name}
          </Text>
          <TouchableOpacity hitSlop={10} onPress={clearAttachment} activeOpacity={0.7}>
            <Ionicons name="close" size={16} color="#737373" />
          </TouchableOpacity>
        </View>
      )}

      {/* Input row */}
      <View style={styles.row}>
        <TouchableOpacity
          activeOpacity={0.7}
          style={styles.iconBtn}
          onPress={pickImage}
          disabled={uploading || sending || disabled}
        >
          <Ionicons name="image-outline" size={22} color="#737373" />
        </TouchableOpacity>

        <View style={styles.inputWrap}>
          <TextInput
            ref={inputRef}
            value={text}
            onChangeText={setText}
            placeholder={placeholder ?? t('chat.placeholder')}
            placeholderTextColor="#a3a3a3"
            multiline
            maxLength={2000}
            editable={!sending && !disabled}
            style={styles.input}
          />
        </View>

        <TouchableOpacity
          activeOpacity={0.7}
          onPress={handleSend}
          disabled={!hasContent || sending || uploading || disabled}
          style={[
            styles.sendBtn,
            { backgroundColor: '#007AFF', opacity: hasContent ? 1 : 0.4 },
          ]}
        >
          {sending || uploading ? (
            <ActivityIndicator size="small" color="#fff" />
          ) : (
            <Ionicons name="arrow-up" size={18} color="#fff" />
          )}
        </TouchableOpacity>
      </View>
    </View>
  );
}

// Base64 → Uint8Array (für Supabase Storage Upload)
function decodeBase64(base64: string): Uint8Array {
  const binary =
    typeof atob === 'function'
      ? atob(base64)
      : Buffer.from(base64, 'base64').toString('binary');
  const len = binary.length;
  const bytes = new Uint8Array(len);
  for (let i = 0; i < len; i++) bytes[i] = binary.charCodeAt(i);
  return bytes;
}

function makeStyles(colors: ReturnType<typeof useColors>) {
  return StyleSheet.create({
    container: {
      backgroundColor: colors.bg,
      borderTopWidth: StyleSheet.hairlineWidth,
      borderTopColor: colors.border,
    },
    replyBar: {
      flexDirection: 'row',
      alignItems: 'center',
      paddingHorizontal: 12,
      paddingVertical: 8,
      backgroundColor: colors.surface,
      borderLeftWidth: 3,
      borderLeftColor: '#007AFF',
      marginHorizontal: 8,
      marginTop: 6,
      borderRadius: 8,
    },
    replyName: {
      fontSize: 11,
      fontFamily: 'Nunito_700Bold',
      color: '#007AFF',
    },
    replyContent: {
      fontSize: 11,
      fontFamily: 'Nunito_400Regular',
      color: colors.textMuted,
      marginTop: 1,
    },
    attachBar: {
      flexDirection: 'row',
      alignItems: 'center',
      paddingHorizontal: 12,
      paddingVertical: 6,
      backgroundColor: colors.surface,
      marginHorizontal: 8,
      marginTop: 6,
      borderRadius: 8,
    },
    attachImg: {
      width: 36,
      height: 36,
      borderRadius: 6,
      marginRight: 8,
    },
    attachFileIcon: {
      width: 36,
      height: 36,
      borderRadius: 6,
      backgroundColor: colors.surfaceElevated,
      alignItems: 'center',
      justifyContent: 'center',
      marginRight: 8,
    },
    attachName: {
      flex: 1,
      fontSize: 12,
      fontFamily: 'Nunito_600SemiBold',
      color: colors.text,
    },
    row: {
      flexDirection: 'row',
      alignItems: 'flex-end',
      gap: 8,
      paddingHorizontal: 12,
      paddingTop: 8,
      paddingBottom: 8,
    },
    iconBtn: {
      width: 38,
      height: 38,
      borderRadius: 19,
      alignItems: 'center',
      justifyContent: 'center',
    },
    inputWrap: {
      flex: 1,
      backgroundColor: colors.surfaceElevated,
      borderRadius: 22,
      paddingVertical: 9,
      paddingHorizontal: 16,
      minHeight: 38,
      maxHeight: 120,
      justifyContent: 'center',
    },
    input: {
      fontSize: 15,
      fontFamily: 'Nunito_400Regular',
      color: colors.text,
      padding: 0,
    },
    sendBtn: {
      width: 38,
      height: 38,
      borderRadius: 19,
      alignItems: 'center',
      justifyContent: 'center',
    },
  });
}
