import AppHeader from "@/components/AppHeader";
import ButtonSaveHeader from "@/components/buttonSaveHeader";
import DrawerBottom from "@/components/drawerBottom";
import { InputForm } from "@/components/inputForm";
import LoadingCenter from "@/components/loadingCenter";
import MenuItemRow from "@/components/menuItemRow";
import Text from "@/components/Text";
import Styles from "@/constants/Styles";
import { apiEditDiscussionGeneral, apiGetDiscussionGeneralOne } from "@/lib/api";
import { setUpdateDiscussionGeneralDetail } from "@/lib/discussionGeneralDetail";
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 { router, Stack, useLocalSearchParams } from "expo-router";
import { useEffect, useState } from "react";
import { Pressable, SafeAreaView, ScrollView, View } from "react-native";
import Toast from "react-native-toast-message";
import { useDispatch, useSelector } from "react-redux";

function getFileIcon(ext: string): keyof typeof MaterialCommunityIcons.glyphMap {
   if (['jpg', 'jpeg', 'png', 'gif', 'webp', 'heic', 'heif'].includes(ext)) return 'image-outline'
   if (ext === 'pdf') return 'file-pdf-box'
   if (['mp4', 'mov', 'avi', 'mkv'].includes(ext)) return 'video-outline'
   if (['doc', 'docx'].includes(ext)) return 'file-word-outline'
   if (['xls', 'xlsx'].includes(ext)) return 'file-excel-outline'
   if (['zip', 'rar', '7z'].includes(ext)) return 'zip-box-outline'
   return 'file-outline'
}

function getFileColor(ext: string): string {
   if (['jpg', 'jpeg', 'png', 'gif', 'webp', 'heic', 'heif'].includes(ext)) return '#339AF0'
   if (ext === 'pdf') return '#F03E3E'
   if (['mp4', 'mov', 'avi', 'mkv'].includes(ext)) return '#AE3EC9'
   if (['doc', 'docx'].includes(ext)) return '#1C7ED6'
   if (['xls', 'xlsx'].includes(ext)) return '#2F9E44'
   if (['zip', 'rar', '7z'].includes(ext)) return '#E8590C'
   return '#868E96'
}

export default function EditDiscussionGeneral() {
   const { token, decryptToken } = useAuthSession();
   const { colors } = useTheme();
   const { id } = useLocalSearchParams<{ id: string }>();
   const [disableBtn, setDisableBtn] = useState(false)
   const dispatch = useDispatch()
   const [loading, setLoading] = useState(false)
   const [fileForm, setFileForm] = useState<any[]>([])
   const [isModalFile, setModalFile] = useState(false)
   const [indexDelFile, setIndexDelFile] = useState<{ id: string | number; cat: "newFile" | "oldFile" }>({ id: "", cat: "newFile" })
   const [dataFile, setDataFile] = useState<{ id: string; idStorage: string; name: string; extension: string; delete?: boolean }[]>([])
   const update = useSelector((state: any) => state.discussionGeneralDetailUpdate)
   const [dataForm, setDataForm] = useState({ title: "", desc: "" });
   const [error, setError] = useState({ title: false, desc: false })

   const visibleOldFiles = dataFile.filter(v => !v.delete)
   const totalFiles = fileForm.length + visibleOldFiles.length

   async function handleLoad() {
      try {
         const hasil = await decryptToken(String(token?.current));
         const response = await apiGetDiscussionGeneralOne({ id, user: hasil, cat: "detail" });
         const responseFile = await apiGetDiscussionGeneralOne({ id, user: hasil, cat: "file" });
         if (response.success) setDataForm(response.data);
         if (responseFile.success) setDataFile(responseFile.data);
      } catch (error) {
         console.error(error);
      }
   }

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

   function validationForm(cat: string, val: any) {
      if (cat === "title") {
         setDataForm({ ...dataForm, title: val });
         setError({ ...error, title: val === "" || val === "null" });
      } else if (cat === "desc") {
         setDataForm({ ...dataForm, desc: val });
         setError({ ...error, desc: val === "" || val === "null" });
      }
   }

   function checkForm() {
      const hasError = Object.values(error).some(v => v)
      const hasEmpty = Object.values(dataForm).some(v => v === "")
      setDisableBtn(hasError || hasEmpty);
   }

   useEffect(() => { checkForm() }, [error, dataForm])

   const pickDocumentAsync = async () => {
      const result = await DocumentPicker.getDocumentAsync({ type: ["*/*"], multiple: true });
      if (!result.canceled) {
         let skipped = 0
         for (const asset of result.assets) {
            if (!asset.uri) continue
            const isDup = fileForm.some(f => f.name === asset.name) ||
               visibleOldFiles.some(f => `${f.name}.${f.extension}` === asset.name)
            if (isDup) {
               skipped++
            } else {
               setFileForm(prev => [...prev, asset])
            }
         }
         if (skipped > 0) Toast.show({ type: 'small', text1: 'Beberapa file sudah ditambahkan' })
      }
   };

   function deleteFile(index: number | string, cat: "newFile" | "oldFile" | null) {
      if (cat === "newFile") {
         setFileForm(fileForm.filter((_, i) => i !== index))
      } else {
         setDataFile(prev => prev.map(item => item.id === index ? { ...item, delete: true } : item))
      }
      setModalFile(false)
   }

   async function handleEdit() {
      try {
         setLoading(true)
         const hasil = await decryptToken(String(token?.current));
         const fd = new FormData()
         for (let i = 0; i < fileForm.length; i++) {
            fd.append(`file${i}`, { uri: fileForm[i].uri, type: 'application/octet-stream', name: fileForm[i].name } as any);
         }
         fd.append("data", JSON.stringify({ user: hasil, title: dataForm.title, desc: dataForm.desc, oldFile: dataFile }))
         const response = await apiEditDiscussionGeneral(fd, id);
         if (response.success) {
            dispatch(setUpdateDiscussionGeneralDetail(!update))
            Toast.show({ type: 'small', text1: 'Berhasil mengubah data' })
            router.back();
         } else {
            Toast.show({ type: 'small', text1: 'Gagal mengubah data' })
         }
      } catch (error: any) {
         console.error(error);
         Toast.show({ type: 'small', text1: error?.response?.data?.message || "Gagal mengubah data" })
      } finally {
         setLoading(false)
      }
   }

   return (
      <SafeAreaView style={[Styles.flex1, { backgroundColor: colors.background }]}>
         <Stack.Screen
            options={{
               header: () => (
                  <AppHeader
                     title="Edit Diskusi"
                     showBack={true}
                     onPressLeft={() => router.back()}
                     right={
                        <ButtonSaveHeader
                           disable={disableBtn || loading}
                           category="update"
                           onPress={() => handleEdit()}
                        />
                     }
                  />
               )
            }}
         />
         {loading && <LoadingCenter />}
         <ScrollView showsVerticalScrollIndicator={false} style={[Styles.h100, Styles.flex1, { backgroundColor: colors.background }]}>
            <View style={Styles.p15}>

               <InputForm
                  label="Judul"
                  type="default"
                  placeholder="Judul"
                  required
                  bg={colors.card}
                  error={error.title}
                  value={dataForm.title}
                  errorText="Judul tidak boleh kosong"
                  onChange={(val) => validationForm("title", val)}
               />

               <InputForm
                  label="Diskusi"
                  type="default"
                  placeholder="Hal yang didiskusikan"
                  required
                  bg={colors.card}
                  error={error.desc}
                  value={dataForm.desc}
                  errorText="Diskusi tidak boleh kosong"
                  onChange={(val) => validationForm("desc", val)}
                  multiline
               />

               {/* File */}
               <View style={[Styles.wrapPaper, Styles.mb15, Styles.sectionCard,
                  { backgroundColor: colors.card, borderColor: colors.icon + '18' }]}>
                  <Pressable
                     onPress={pickDocumentAsync}
                     style={[Styles.sectionActionRow, { marginBottom: totalFiles > 0 ? 12 : 0 }]}
                  >
                     <View style={[Styles.sectionIconBox, { backgroundColor: colors.icon + '15' }]}>
                        <MaterialCommunityIcons name="paperclip" size={18} color={colors.dimmed} />
                     </View>
                     <View style={Styles.flex1}>
                        <Text style={[Styles.textDefaultSemiBold, { color: colors.text }]}>File</Text>
                        {totalFiles === 0 && (
                           <Text style={[Styles.textMediumNormal, { color: colors.dimmed }]}>Opsional — ketuk untuk upload</Text>
                        )}
                     </View>
                     {totalFiles > 0 && (
                        <View style={[Styles.sectionBadge, { backgroundColor: colors.dimmed + '18' }]}>
                           <Text style={[Styles.textSmallSemiBold, { color: colors.dimmed }]}>{totalFiles} file</Text>
                        </View>
                     )}
                     <MaterialCommunityIcons name="chevron-right" size={18} color={colors.dimmed} />
                  </Pressable>
                  {totalFiles > 0 && (
                     <View style={Styles.fileGrid}>
                        {visibleOldFiles.map((item, index) => {
                           const ext = item.extension.toLowerCase()
                           const iconName = getFileIcon(ext)
                           const iconColor = getFileColor(ext)
                           return (
                              <Pressable
                                 key={`old-${index}`}
                                 onPress={() => { setIndexDelFile({ id: item.id, cat: "oldFile" }); setModalFile(true) }}
                                 style={[Styles.fileCard, { backgroundColor: 'transparent', borderColor: colors.icon + '18' }]}
                              >
                                 <View style={[Styles.sectionIconBox, { backgroundColor: iconColor + '20' }]}>
                                    <MaterialCommunityIcons name={iconName} size={18} color={iconColor} />
                                 </View>
                                 <View style={Styles.flex1}>
                                    <Text style={Styles.textDefault} numberOfLines={1}>{item.name}</Text>
                                    <Text style={[Styles.textSmallSemiBold, { color: colors.dimmed }]}>{ext.toUpperCase()}</Text>
                                 </View>
                              </Pressable>
                           )
                        })}
                        {fileForm.map((item, index) => {
                           const ext = item.name.split('.').pop()?.toLowerCase() ?? ''
                           const baseName = item.name.includes('.') ? item.name.split('.').slice(0, -1).join('.') : item.name
                           const iconName = getFileIcon(ext)
                           const iconColor = getFileColor(ext)
                           return (
                              <Pressable
                                 key={`new-${index}`}
                                 onPress={() => { setIndexDelFile({ id: index, cat: "newFile" }); setModalFile(true) }}
                                 style={[Styles.fileCard, { backgroundColor: 'transparent', borderColor: colors.icon + '18' }]}
                              >
                                 <View style={[Styles.sectionIconBox, { backgroundColor: iconColor + '20' }]}>
                                    <MaterialCommunityIcons name={iconName} size={18} color={iconColor} />
                                 </View>
                                 <View style={Styles.flex1}>
                                    <Text style={Styles.textDefault} numberOfLines={1}>{baseName}</Text>
                                    <Text style={[Styles.textSmallSemiBold, { color: colors.dimmed }]}>{ext.toUpperCase()}</Text>
                                 </View>
                              </Pressable>
                           )
                        })}
                     </View>
                  )}
               </View>

            </View>
         </ScrollView>

         <DrawerBottom animation="slide" isVisible={isModalFile} setVisible={setModalFile} title="Menu">
            <View style={Styles.rowItemsCenter}>
               <MenuItemRow
                  icon={<Ionicons name="trash-outline" color={colors.text} size={25} />}
                  title="Hapus"
                  onPress={() => deleteFile(indexDelFile.id, indexDelFile.cat)}
               />
            </View>
         </DrawerBottom>
      </SafeAreaView>
   );
}
