import { View, TouchableOpacity, Image } from "react-native";
import React, { useState, useEffect, useCallback } from "react";
import { useTailwind } from "tailwind-rn";
import { Icon } from "@rneui/themed";
import Toast from "react-native-toast-message";
import { DraggableGrid } from "react-native-draggable-grid";
import { useImageViewer } from "../../context/ImageViewProvider";
import VideoModal from "../VideoModal";
import * as ImagePicker from "expo-image-picker";
import * as VideoThumbnails from "expo-video-thumbnails";

/*
props格式：
  setDragging            返回正在拖动的状态，用于该组件嵌套在ScrollView中的时候禁用ScrollView的滚动
  type                   选择的媒体类型 "image"|"video"|"mix"
  maxCount               最大选择数量
  setAssets              向父组件返回媒体
 */

export default function MediaPicker({
  setDragging = () => null,
  maxCount,
  type = "image",
  setAssets,
}) {
  const tailwind = useTailwind();
  const [newAssets, setNewAssets] = useState([]);
  const [_assets, set_Assets] = useState([]);

  const { showImageViewer } = useImageViewer();

  const [showVideo, setShowVideo] = useState(false);
  const [videoUrl, setVideoUrl] = useState("");

  //为视频生成封面
  const generateThumbnail = useCallback(async (uri) => {
    try {
      const videoCover = await VideoThumbnails.getThumbnailAsync(uri);
      return videoCover;
    } catch (e) {
      console.warn(e);
    }
  }, []);

  //选择媒体
  const pickMedia = async () => {
    let mediaType;
    if (type === "image") {
      mediaType = ImagePicker.MediaTypeOptions.Images;
    } else if (type === "video") {
      mediaType = ImagePicker.MediaTypeOptions.Videos;
    } else {
      mediaType = ImagePicker.MediaTypeOptions.All;
    }
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: mediaType,
      allowsMultipleSelection: true,
      selectionLimit: maxCount - _assets.length,
      quality: 1,
    });

    if (!result.canceled) {
      for (let i = 0; i < result.assets.length; i++) {
        if (result.assets[i].duration > 0) {
          const videoCover = await generateThumbnail(result.assets[i].uri);
          result.assets[i].cover = videoCover.uri;
        }
      }
      setNewAssets(result.assets);
    }
  };

  //当newAssets改变的时候添加新数据到assets
  useEffect(() => {
    const temAssets = newAssets.map((item) => ({
      ...item,
      key: Date.now().toString(36) + Math.random().toString(36),
    }));
    set_Assets([..._assets, ...temAssets]);
    setAssets([..._assets, ...temAssets]);
  }, [newAssets]);

  //加号选择器
  const Picker = () => {
    return (
      <TouchableOpacity
        onPress={() => {
          //数量检查
          maxCount - _assets.length !== 0
            ? pickMedia()
            : Toast.show({
                type: "error",
                text1: `已达到最大选择数量`,
                topOffset: 60,
              });
        }}
        style={{
          aspectRatio: 1,
          padding: 2,
          ...tailwind("w-1/4"),
        }}
      >
        <View
          style={tailwind(
            "border border-dashed border-gray-400 rounded flex-1 justify-center items-center"
          )}
        >
          <Icon type="ionicon" name="add" color="#9ca3af" size={40} />
        </View>
      </TouchableOpacity>
    );
  };

  const renderItem = (item) => {
    const handleDelete = () => {
      const updatedAssets = _assets.filter((_item) => _item.key !== item.key);
      set_Assets(updatedAssets);
      setAssets(updatedAssets);
    };

    return (
      <View
        activeOpacity={1}
        style={{
          aspectRatio: 1,
          padding: 2,
          ...tailwind("w-full"),
        }}
        key={item.key}
      >
        <Image
          src={item.cover ? item.cover : item.uri}
          style={tailwind("w-full h-full rounded")}
        />
        <View style={{ zIndex: 999, ...tailwind("absolute top-2 right-2") }}>
          <Icon
            type="ionicon"
            name="close"
            color="white"
            size={18}
            onPress={handleDelete}
            style={tailwind("bg-black rounded-full opacity-70")}
          />
        </View>
        {item.duration > 0 && (
          <View
            style={tailwind(
              "absolute flex w-full h-full items-center justify-center"
            )}
          >
            <Icon
              type="ionicon"
              name="play"
              color="white"
              size={14}
              style={tailwind("bg-black p-2 rounded-full opacity-70")}
            />
          </View>
        )}
      </View>
    );
  };

  return (
    <View style={tailwind("flex flex-col w-full")}>
      <DraggableGrid
        numColumns={4}
        renderItem={renderItem}
        data={_assets}
        onDragStart={() => setDragging(true)}
        onDragRelease={(data) => {
          set_Assets(data);
          setAssets(data);
          setDragging(false);
        }}
        onItemPress={(item) => {
          if (!item.duration) {
            showImageViewer({
              imageUrls: [{ url: item.uri }],
              index: 0,
            });
            return;
          }
          setVideoUrl(item.uri);
          setShowVideo(true);
        }}
      />
      <Picker />
      <VideoModal
        visible={showVideo}
        setVisible={setShowVideo}
        url={videoUrl}
      />
    </View>
  );
}
