import AppHeader from "@/components/AppHeader";
import BorderBottomItem from "@/components/borderBottomItem";
import { ButtonForm } from "@/components/buttonForm";
import ButtonSelect from "@/components/buttonSelect";
import DrawerBottom from "@/components/drawerBottom";
import MenuItemRow from "@/components/menuItemRow";
import ModalConfirmation from "@/components/ModalConfirmation";
import ModalLoading from "@/components/modalLoading";
import Skeleton from "@/components/skeleton";
import Text from "@/components/Text";
import { ConstEnv } from "@/constants/ConstEnv";
import Styles from "@/constants/Styles";
import {
   apiAddProjectTaskFile,
   apiDeleteProjectTaskFile,
   apiGetProjectOne,
   apiGetProjectTaskFile,
   apiLinkProjectTaskFile,
} from "@/lib/api";
import { setUpdateProject } from "@/lib/projectUpdate";
import { useAuthSession } from "@/providers/AuthProvider";
import { useTheme } from "@/providers/ThemeProvider";
import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons";
import * as DocumentPicker from "expo-document-picker";
import * as FileSystem from "expo-file-system";
import { startActivityAsync } from "expo-intent-launcher";
import { router, Stack, useLocalSearchParams } from "expo-router";
import * as Sharing from "expo-sharing";
import { useEffect, useState } from "react";
import {
   ActivityIndicator,
   Alert,
   Platform,
   SafeAreaView,
   ScrollView,
   View,
} from "react-native";
import * as mime from "react-native-mime-types";
import Toast from "react-native-toast-message";
import { useDispatch, useSelector } from "react-redux";

type FileItem = {
   id: string;      // ProjectTaskFile.id
   idFile: string;  // ProjectFile.id
   name: string;
   extension: string;
   idStorage: string;
};

type ProjectFile = {
   id: string;
   name: string;
   extension: string;
   idStorage: string;
};

export default function ProjectTugasFileScreen() {
   const { colors } = useTheme();
   const { id, taskId, member: memberParam } = useLocalSearchParams<{ id: string; taskId: string; member: string }>();
   const { token, decryptToken } = useAuthSession();
   const dispatch = useDispatch();
   const update = useSelector((state: any) => state.projectUpdate);
   const entityUser = useSelector((state: any) => state.user);
   const isMember = memberParam === "true";
   const canEdit = isMember || (entityUser.role !== "user" && entityUser.role !== "coadmin");

   const [data, setData] = useState<FileItem[]>([]);
   const [loading, setLoading] = useState(true);
   const [loadingOpen, setLoadingOpen] = useState(false);
   const [loadingUpload, setLoadingUpload] = useState(false);
   const [loadingLink, setLoadingLink] = useState(false);

   const [selectFile, setSelectFile] = useState<FileItem | null>(null);
   const [isMenuModal, setMenuModal] = useState(false);
   const [showDeleteModal, setShowDeleteModal] = useState(false);

   const [projectFiles, setProjectFiles] = useState<ProjectFile[]>([]);
   const [isPickerModal, setPickerModal] = useState(false);
   const [loadingProjectFiles, setLoadingProjectFiles] = useState(false);
   const [selectedProjectFiles, setSelectedProjectFiles] = useState<string[]>([]);

   const arrSkeleton = Array.from({ length: 4 });

   async function loadFiles() {
      try {
         setLoading(true);
         const hasil = await decryptToken(String(token?.current));
         const response = await apiGetProjectTaskFile({ user: hasil, id: taskId });
         setData(response.data ?? []);
      } catch (error) {
         console.error(error);
      } finally {
         setLoading(false);
      }
   }

   async function loadProjectFiles() {
      try {
         setLoadingProjectFiles(true);
         const hasil = await decryptToken(String(token?.current));
         const response = await apiGetProjectOne({ user: hasil, cat: "file", id });
         setProjectFiles(response.data ?? []);
      } catch (error) {
         console.error(error);
      } finally {
         setLoadingProjectFiles(false);
      }
   }

   useEffect(() => {
      loadFiles();
   }, []);

   const openFile = () => {
      setMenuModal(false);
      setLoadingOpen(true);
      const remoteUrl = ConstEnv.url_storage + "/files/" + selectFile?.idStorage;
      const fileName = selectFile?.name + "." + selectFile?.extension;
      const localPath = `${FileSystem.documentDirectory}/${fileName}`;
      const mimeType = mime.lookup(fileName);

      FileSystem.downloadAsync(remoteUrl, localPath).then(async ({ uri }) => {
         const contentURL = await FileSystem.getContentUriAsync(uri);
         try {
            if (Platform.OS === "android") {
               await startActivityAsync("android.intent.action.VIEW", {
                  data: contentURL,
                  flags: 1,
                  type: mimeType as string,
               });
            } else {
               Sharing.shareAsync(localPath);
            }
         } catch {
            Alert.alert("INFO", "Gagal membuka file, tidak ada aplikasi yang dapat membuka file ini");
         } finally {
            setLoadingOpen(false);
         }
      });
   };

   async function handleDelete() {
      try {
         const hasil = await decryptToken(String(token?.current));
         const response = await apiDeleteProjectTaskFile({ user: hasil }, String(selectFile?.id));
         if (response.success) {
            Toast.show({ type: "small", text1: "Berhasil menghapus file" });
            dispatch(setUpdateProject({ ...update, task: !update.task }));
            loadFiles();
         } else {
            Toast.show({ type: "small", text1: response.message });
         }
      } catch (error: any) {
         const message = error?.response?.data?.message || "Gagal menghapus file";
         Toast.show({ type: "small", text1: message });
      } finally {
         setMenuModal(false);
      }
   }

   async function handleUpload() {
      const result = await DocumentPicker.getDocumentAsync({ type: ["*/*"], multiple: true });
      if (result.canceled) return;

      try {
         setLoadingUpload(true);
         const hasil = await decryptToken(String(token?.current));
         const fd = new FormData();

         for (let i = 0; i < result.assets.length; i++) {
            fd.append(`file${i}`, {
               uri: result.assets[i].uri,
               type: "application/octet-stream",
               name: result.assets[i].name,
            } as any);
         }
         fd.append("data", JSON.stringify({ user: hasil }));

         const response = await apiAddProjectTaskFile({ data: fd, id: taskId });
         if (response.success) {
            Toast.show({ type: "small", text1: "Berhasil menambahkan file" });
            dispatch(setUpdateProject({ ...update, task: !update.task }));
            loadFiles();
         } else {
            Toast.show({ type: "small", text1: response.message });
         }
      } catch (error: any) {
         const message = error?.response?.data?.message || "Gagal menambahkan file";
         Toast.show({ type: "small", text1: message });
      } finally {
         setLoadingUpload(false);
      }
   }

   function toggleProjectFileSelect(fileId: string) {
      setSelectedProjectFiles((prev) =>
         prev.includes(fileId) ? prev.filter((v) => v !== fileId) : [...prev, fileId]
      );
   }

   async function handleLinkFiles() {
      if (selectedProjectFiles.length === 0) return;
      try {
         setLoadingLink(true);
         const hasil = await decryptToken(String(token?.current));
         for (const idFile of selectedProjectFiles) {
            await apiLinkProjectTaskFile({ user: hasil, idFile, id: taskId });
         }
         Toast.show({ type: "small", text1: "Berhasil menambahkan file" });
         dispatch(setUpdateProject({ ...update, task: !update.task }));
         setPickerModal(false);
         setSelectedProjectFiles([]);
         loadFiles();
      } catch (error: any) {
         const message = error?.response?.data?.message || "Gagal menambahkan file";
         Toast.show({ type: "small", text1: message });
      } finally {
         setLoadingLink(false);
      }
   }

   const attachedFileIds = new Set(data.map((f) => f.idFile));

   return (
      <SafeAreaView style={{ flex: 1, backgroundColor: colors.background }}>
         <Stack.Screen
            options={{
               header: () => (
                  <AppHeader
                     title="File Tugas"
                     showBack={true}
                     onPressLeft={() => router.back()}
                  />
               ),
            }}
         />
         <ModalLoading isVisible={loadingOpen} setVisible={setLoadingOpen} />

         <ScrollView>
            <View style={[Styles.p15, Styles.mb100]}>
               {canEdit && (
                  <>
                     <ButtonSelect
                        value="Upload dari Perangkat"
                        onPress={handleUpload}
                        disabled={loadingUpload}
                     />
                     <ButtonSelect
                        value="Pilih dari File Kegiatan ini"
                        onPress={() => {
                           setSelectedProjectFiles([]);
                           setPickerModal(true);
                           loadProjectFiles();
                        }}
                     />
                  </>
               )}

               {loadingUpload && <ActivityIndicator size="small" style={Styles.mv05} />}

               <View style={[Styles.mb15, Styles.mt10]}>
                  <Text style={[Styles.textDefaultSemiBold, Styles.mv05]}>File Terlampir</Text>
                  <View style={[Styles.wrapPaper, { backgroundColor: colors.card, borderColor: colors.background }]}>
                     {loading ? (
                        arrSkeleton.map((_, index) => (
                           <Skeleton key={index} width={100} height={40} widthType="percent" borderRadius={10} />
                        ))
                     ) : data.length > 0 ? (
                        data.map((item, index) => (
                           <BorderBottomItem
                              key={index}
                              borderType="all"
                              icon={<MaterialCommunityIcons name="file-outline" size={25} color={colors.text} />}
                              title={item.name + "." + item.extension}
                              titleWeight="normal"
                              onPress={() => {
                                 setSelectFile(item);
                                 setMenuModal(true);
                              }}
                           />
                        ))
                     ) : (
                        <Text style={[Styles.textDefault, { textAlign: "center", color: colors.dimmed }]}>
                           Tidak ada file
                        </Text>
                     )}
                  </View>
               </View>
            </View>
         </ScrollView>

         {/* Menu per file */}
         <DrawerBottom animation="slide" isVisible={isMenuModal} setVisible={setMenuModal} title="Menu">
            <View style={Styles.rowItemsCenter}>
               <MenuItemRow
                  icon={<MaterialCommunityIcons name="file-eye" color={colors.text} size={25} />}
                  title="Lihat / Share"
                  onPress={openFile}
               />
               {canEdit && (
                  <MenuItemRow
                     icon={<Ionicons name="trash-outline" color={colors.text} size={25} />}
                     title="Hapus"
                     onPress={() => {
                        setMenuModal(false);
                        setTimeout(() => setShowDeleteModal(true), 600);
                     }}
                  />
               )}
            </View>
         </DrawerBottom>

         <ModalConfirmation
            visible={showDeleteModal}
            title="Konfirmasi"
            message="Apakah Anda yakin ingin menghapus file ini?"
            onConfirm={() => {
               setShowDeleteModal(false);
               handleDelete();
            }}
            onCancel={() => setShowDeleteModal(false)}
            confirmText="Hapus"
            cancelText="Batal"
         />

         {/* Picker file dari proyek */}
         <DrawerBottom
            animation="slide"
            isVisible={isPickerModal}
            setVisible={setPickerModal}
            title="Pilih File Proyek"
            height={60}
         >
            <ScrollView>
               {loadingProjectFiles ? (
                  <ActivityIndicator size="small" />
               ) : projectFiles.length > 0 ? (
                  projectFiles.map((item, index) => {
                     const isAttached = attachedFileIds.has(item.id);
                     const isSelected = selectedProjectFiles.includes(item.id);
                     return (
                        <View key={index} style={isAttached ? { opacity: 0.4 } : undefined}>
                           <BorderBottomItem
                              borderType="bottom"
                              icon={
                                 isAttached || isSelected ? (
                                    <Ionicons name="checkmark-circle" size={25} color={colors.primary} />
                                 ) : (
                                    <MaterialCommunityIcons name="file-outline" size={25} color={colors.text} />
                                 )
                              }
                              title={item.name + "." + item.extension}
                              titleWeight="normal"
                              onPress={() => !isAttached && toggleProjectFileSelect(item.id)}
                              bgColor="transparent"
                           />
                        </View>
                     );
                  })
               ) : (
                  <Text style={[Styles.textDefault, { textAlign: "center", color: colors.dimmed }]}>
                     Tidak ada file tersedia
                  </Text>
               )}
            </ScrollView>
            {projectFiles.length > 0 && (
               <View>
                  <ButtonForm
                     text={loadingLink ? "Menyimpan..." : `Tambahkan (${selectedProjectFiles.length})`}
                     disabled={selectedProjectFiles.length === 0 || loadingLink}
                     onPress={handleLinkFiles} />
               </View>
            )}
         </DrawerBottom>
      </SafeAreaView>
   );
}
