import { AntDesign as Icon } from '@expo/vector-icons';
import * as DocumentPicker from 'expo-document-picker';
import * as ImagePicker from 'expo-image-picker';
import React, { useEffect, useState } from 'react';
import {
  Dimensions,
  Image,
  ScrollView,
  Text,
  TouchableOpacity,
  View
} from 'react-native';
import Colors from '../../constants/colors';

const { height } = Dimensions.get('window');

interface FileData {
  key: number;
  uri: string;
  type: string;
  data?: string;
  name?: string;
  size?: string;
}

interface ArrayComponentProps {
  type: 'image' | 'video' | 'docs';
  value?: FileData[];
  updateFormikData: (data: FileData[]) => void;
}

const ArrayComponent: React.FC<ArrayComponentProps> = ({ type, value, updateFormikData }) => {
  const [data, setData] = useState<FileData[]>([]);
  const [error, setError] = useState<string>('');

  useEffect(() => {
    if (Array.isArray(value)) {
      setData(value);
    }
  }, [value]);

  const bytesToSize = (bytes: number) => {
    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
    if (bytes === 0) return '0 Byte';
    const i = Math.floor(Math.log(bytes) / Math.log(1024));
    return `${Math.round(bytes / Math.pow(1024, i))} ${sizes[i]}`;
  };

  const handleAddFile = async () => {
    if (type !== 'docs') {
      // Image or video picker
      const result = await ImagePicker.launchImageLibraryAsync({
        mediaTypes: type === 'image' ? ImagePicker.MediaTypeOptions.Images : ImagePicker.MediaTypeOptions.Videos,
        quality: 0.1,
      });

      if (!result.canceled) {
        const asset = result.assets[0];
      const newFile: FileData = {
            key: data.length ? data[data.length - 1].key + 1 : 0,
            uri: asset.uri,
            type: type === 'image' ? asset.type ?? 'image/jpeg' : 'video/mp4',
            data: asset.base64 ?? undefined,          // convert null to undefined
            name: asset.fileName ?? `file${data.length + 1}.${type === 'image' ? 'jpg' : 'mp4'}`,
            size: asset.fileSize ? bytesToSize(asset.fileSize) : undefined,
        };
        setData(prev => [...prev, newFile]);
      }
    } else {
      // Document picker
      const result = await DocumentPicker.getDocumentAsync({ multiple: true });
      if (!result.canceled && result.assets && result.assets.length > 0) {
        result.assets.forEach((asset, idx) => {
          const newFile: FileData = {
            key: data.length ? data[data.length - 1].key + 1 + idx : idx,
            uri: asset.uri,
            type: asset.mimeType || '',
            name: asset.name,
            size: asset.size ? bytesToSize(asset.size) : undefined,
          };
          setData(prev => [...prev, newFile]);
        });
      }
    }
  };

  const handleRemoveFile = (key: number) => {
    setData(prev => prev.filter(d => d.key !== key));
  };

  const saveData = () => {
    updateFormikData(data);
  };

  return (
    <View style={{ width: '90%' }}>
      {error.length > 0 && <Text style={{ color: 'red', marginBottom: 8 }}>{error}</Text>}
      {type === 'docs' && (
        <Text style={{ color: Colors.colorText, marginBottom: 8 }}>
          Only <Text style={{ fontStyle: 'italic', fontWeight: '700' }}>".doc, .docx, .pdf, .xlsx, .xls"</Text> files are allowed
        </Text>
      )}
      {data.length > 0 && (
        <Text style={{ color: 'black' }}>
          Attachments <Text style={{ color: Colors.buttonColor }}>({data.length} {data.length > 1 ? 'files' : 'file'})</Text>
        </Text>
      )}
      <ScrollView style={{ height: data.length > 0 ? height / 2.5 : 0, marginTop: 10, marginBottom: 10 }}>
        {data.map((item, index) => (
          <View key={item.key} style={{ flexDirection: 'row', alignItems: 'center', marginBottom: 12 }}>
            <Image style={{ height: 50, width: 50 }} source={{ uri: item.data ? `data:image/jpeg;base64,${item.data}` : item.uri }} />
            <View style={{ marginLeft: 10, flex: 2, marginRight: 32 }}>
              <Text style={{ color: Colors.buttonColor, fontSize: 12 }} numberOfLines={1} ellipsizeMode="tail">
                {item.name || `file00${index + 1}`}
              </Text>
              <Text style={{ color: 'black', fontSize: 12 }}>{item.size}</Text>
            </View>
            <Icon name="close-circle" size={20} color={Colors.colorPlaceholder} onPress={() => handleRemoveFile(item.key)} />
          </View>
        ))}
      </ScrollView>
      <TouchableOpacity
        disabled={data.length > 4}
        style={{ padding: 8, backgroundColor: Colors.buttonColor, borderRadius: 5, marginBottom: 10 }}
        onPress={handleAddFile}
      >
        <Text style={{ color: 'white', textAlign: 'center' }}>Add {type === 'docs' ? 'Document' : type}</Text>
      </TouchableOpacity>
      <TouchableOpacity style={{ padding: 8, backgroundColor: 'green', borderRadius: 5 }} onPress={saveData}>
        <Text style={{ color: 'white', textAlign: 'center' }}>Save</Text>
      </TouchableOpacity>
    </View>
  );
};

export { ArrayComponent };

