import HeaderRightAnnouncementDetail from "@/components/announcement/headerAnnouncementDetail";
import AppHeader from "@/components/AppHeader";
import Skeleton from "@/components/skeleton";
import Text from '@/components/Text';
import ErrorView from "@/components/ErrorView";
import { ConstEnv } from "@/constants/ConstEnv";
import { isImageFile } from "@/constants/FileExtensions";
import Styles from "@/constants/Styles";
import { apiGetAnnouncementOne } from "@/lib/api";
import { useAuthSession } from "@/providers/AuthProvider";
import { useTheme } from "@/providers/ThemeProvider";
import { MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons";
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 React, { useEffect, useState } from "react";
import { Dimensions, Platform, Pressable, RefreshControl, SafeAreaView, ScrollView, View } from "react-native";
import ImageViewing from 'react-native-image-viewing';
import * as mime from 'react-native-mime-types';
import RenderHTML from 'react-native-render-html';
import Toast from "react-native-toast-message";
import { useSelector } from "react-redux";

interface AnnouncementData {
   id: string;
   title: string;
   desc: string;
}

interface FileData {
   id: string;
   idStorage: string;
   name: string;
   extension: string;
}

interface MemberData {
   group: string;
   division: string;
}

interface ApiResponse {
   success: boolean;
   data: AnnouncementData;
   member: Record<string, MemberData[]>;
   file: FileData[];
   message: string;
}

export default function DetailAnnouncement() {
   const { id } = useLocalSearchParams<{ id: string }>();
   const { token, decryptToken } = useAuthSession()
   const { colors } = useTheme();
   const [data, setData] = useState<AnnouncementData>({ id: '', title: '', desc: '' })
   const [dataMember, setDataMember] = useState<Record<string, MemberData[]>>({})
   const [dataFile, setDataFile] = useState<FileData[]>([])
   const update = useSelector((state: any) => state.announcementUpdate)
   const entityUser = useSelector((state: any) => state.user)
   const contentWidth = Dimensions.get('window').width - 62
   const [loading, setLoading] = useState(true)
   const [refreshing, setRefreshing] = useState(false)
   const [loadingOpen, setLoadingOpen] = useState(false)
   const [preview, setPreview] = useState(false)
   const [chooseFile, setChooseFile] = useState<FileData>()
   const [isError, setIsError] = useState(false)

   const themed = {
      background:      { backgroundColor: colors.background },
      card:            { backgroundColor: colors.card, borderColor: colors.icon + '18' },
      iconBox:         { backgroundColor: colors.icon + '18' },
      sectionLabel:    { color: colors.dimmed },
      titleText:       { color: colors.text },
      fileChipBorder:  { borderColor: colors.icon + '30' },
      fileChipPressed: { backgroundColor: colors.icon + '10' },
      groupSeparator:  { borderTopColor: colors.icon + '18' },
      divisionIconBg:  { backgroundColor: colors.icon + '15' },
   }

   function handleChooseFile(item: FileData) {
      setChooseFile(item)
      setPreview(true)
   }

   async function handleLoad(loading: boolean) {
      try {
         setIsError(false)
         setLoading(loading)
         const hasil = await decryptToken(String(token?.current))
         const response: ApiResponse = await apiGetAnnouncementOne({ id: id, user: hasil })
         if (response.success) {
            setData(response.data)
            setDataMember(response.member)
            setDataFile(response.file)
         } else {
            setIsError(true)
            Toast.show({ type: 'small', text1: response.message })
         }
      } catch (error: any) {
         console.error(error);
         setIsError(true)
         const message = error?.response?.data?.message || "Gagal mengambil data"
         Toast.show({ type: 'small', text1: message })
      } finally {
         setLoading(false)
      }
   }

   useEffect(() => { handleLoad(false) }, [update])
   useEffect(() => { handleLoad(true) }, [])

   function hasHtmlTags(text: string) {
      return /<[a-z][\s\S]*>/i.test(text);
   }

   const handleRefresh = async () => {
      setRefreshing(true)
      handleLoad(false)
      await new Promise(resolve => setTimeout(resolve, 2000));
      setRefreshing(false)
   };

   const openFile = async (item: FileData) => {
      try {
         setLoadingOpen(true);
         const remoteUrl = ConstEnv.url_storage + '/files/' + item.idStorage;
         const fileName = item.name + '.' + item.extension;
         const localPath = `${FileSystem.documentDirectory}/${fileName}`;
         const mimeType = mime.lookup(fileName);
         const downloadResult = await FileSystem.downloadAsync(remoteUrl, localPath);
         if (downloadResult.status !== 200) {
            throw new Error(`Download failed with status ${downloadResult.status}`);
         }
         const contentURL = await FileSystem.getContentUriAsync(downloadResult.uri);
         try {
            if (Platform.OS === 'android') {
               await startActivityAsync('android.intent.action.VIEW', {
                  data: contentURL,
                  flags: 1,
                  type: mimeType as string,
               });
            } else if (Platform.OS === 'ios') {
               await Sharing.shareAsync(localPath);
            }
         } catch {
            Toast.show({ type: 'error', text1: 'Tidak ada aplikasi yang dapat membuka file ini' });
         }
      } catch {
         Toast.show({ type: 'error', text1: 'Gagal membuka file', text2: 'Silakan coba lagi nanti' });
      } finally {
         setLoadingOpen(false);
      }
   };

   return (
      <SafeAreaView style={[Styles.flex1, themed.background]}>
         <Stack.Screen
            options={{
               header: () => (
                  <AppHeader
                     title="Pengumuman"
                     showBack={true}
                     onPressLeft={() => router.back()}
                     right={entityUser.role != 'user' && entityUser.role != 'coadmin'
                        ? <HeaderRightAnnouncementDetail id={id} />
                        : <></>
                     }
                  />
               )
            }}
         />
         <ScrollView
            showsVerticalScrollIndicator={false}
            style={[Styles.flex1, themed.background]}
            refreshControl={
               <RefreshControl refreshing={refreshing} onRefresh={handleRefresh} tintColor={colors.icon} />
            }
         >
            {isError && !loading ? (
               <View style={Styles.mv50}>
                  <ErrorView />
               </View>
            ) : (
               <View style={Styles.announcementDetailContainer}>

                  {/* Title + Description */}
                  <View style={[Styles.wrapPaper, Styles.noShadow, Styles.sectionCard, Styles.announcementDetailCard, themed.card]}>
                     {loading ? (
                        <View style={Styles.announcementDetailSkeletonGap}>
                           <View style={[Styles.rowItemsCenter, Styles.announcementDetailSkeletonIconRow]}>
                              <Skeleton width={38} height={38} borderRadius={10} />
                              <Skeleton width={60} widthType="percent" height={16} borderRadius={6} />
                           </View>
                           <Skeleton width={100} widthType="percent" height={10} borderRadius={6} />
                           <Skeleton width={100} widthType="percent" height={10} borderRadius={6} />
                           <Skeleton width={80} widthType="percent" height={10} borderRadius={6} />
                        </View>
                     ) : (
                        <>
                           <View style={[Styles.rowItemsCenter, Styles.announcementDetailTitleRow]}>
                              <View style={[Styles.sectionIconBox, Styles.announcementDetailIconBox, themed.iconBox]}>
                                 <MaterialIcons name="campaign" size={22} color={colors.icon} />
                              </View>
                              <Text style={[Styles.textDefaultSemiBold, Styles.announcementDetailTitleText, themed.titleText]} numberOfLines={2}>
                                 {data.title}
                              </Text>
                           </View>
                           {hasHtmlTags(data.desc)
                              ? <RenderHTML
                                 contentWidth={contentWidth}
                                 source={{ html: data.desc }}
                                 baseStyle={{ color: colors.text }}
                              />
                              : <Text style={Styles.textDefault}>{data.desc}</Text>
                           }
                        </>
                     )}
                  </View>

                  {/* Files */}
                  {dataFile.length > 0 && (
                     <View>
                        <View style={[Styles.rowItemsCenter, Styles.announcementDetailSectionLabelRow]}>
                           <MaterialCommunityIcons name="paperclip" size={14} color={colors.dimmed} />
                           <Text style={[Styles.textInformation, themed.sectionLabel]}>
                              Lampiran ({dataFile.length})
                           </Text>
                        </View>
                        <View style={[Styles.wrapPaper, Styles.noShadow, Styles.sectionCard, Styles.announcementDetailCard, Styles.announcementDetailFileCardPadding, themed.card]}>
                           <ScrollView horizontal showsHorizontalScrollIndicator={false}>
                              <View style={[Styles.rowItemsCenter, Styles.announcementDetailFileChipList]}>
                                 {dataFile.map((item, index) => (
                                    <Pressable
                                       key={`${item.id}-${index}`}
                                       onPress={() => isImageFile(item.extension) ? handleChooseFile(item) : openFile(item)}
                                       style={({ pressed }) => [Styles.announcementDetailFileChip, themed.fileChipBorder,
                                          pressed ? themed.fileChipPressed : themed.background]}
                                    >
                                       <MaterialCommunityIcons
                                          name={isImageFile(item.extension) ? "file-image-outline" : "file-document-outline"}
                                          size={16}
                                          color={colors.icon}
                                       />
                                       <Text style={[Styles.textInformation, Styles.announcementDetailFileChipText, themed.titleText]} numberOfLines={1}>
                                          {item.name}.{item.extension}
                                       </Text>
                                    </Pressable>
                                 ))}
                              </View>
                           </ScrollView>
                        </View>
                     </View>
                  )}

                  {/* Recipients */}
                  <View>
                     <View style={[Styles.rowItemsCenter, Styles.announcementDetailSectionLabelRow]}>
                        <MaterialIcons name="groups" size={14} color={colors.dimmed} />
                        <Text style={[Styles.textInformation, themed.sectionLabel]}>
                           Ditujukan Kepada
                        </Text>
                     </View>
                     <View style={[Styles.wrapPaper, Styles.noShadow, Styles.sectionCard, Styles.announcementDetailCard, themed.card]}>
                        {loading ? (
                           <View style={Styles.announcementDetailRecipientGap}>
                              <Skeleton width={40} widthType="percent" height={10} borderRadius={6} />
                              <Skeleton width={100} widthType="percent" height={10} borderRadius={6} />
                              <Skeleton width={60} widthType="percent" height={10} borderRadius={6} />
                              <Skeleton width={100} widthType="percent" height={10} borderRadius={6} />
                           </View>
                        ) : (
                           Object.keys(dataMember).map((v, i) => (
                              <View key={i} style={i > 0 ? [Styles.announcementDetailGroupSeparator, themed.groupSeparator] : undefined}>
                                 <Text style={[Styles.textInformation, Styles.announcementDetailGroupLabel, themed.sectionLabel]}>
                                    {dataMember[v]?.[0].group}
                                 </Text>
                                 <View>
                                    {dataMember[v].map((item, x) => (
                                       <View key={x} style={[Styles.rowItemsCenter, Styles.announcementDetailDivisionRow]}>
                                          <View style={[Styles.announcementDetailDivisionIconCircle, themed.divisionIconBg]}>
                                             <MaterialIcons name="group" size={14} color={colors.icon} />
                                          </View>
                                          <Text style={[Styles.textDefault, Styles.flex1, themed.titleText]}>
                                             {item.division}
                                          </Text>
                                       </View>
                                    ))}
                                 </View>
                              </View>
                           ))
                        )}
                     </View>
                  </View>

               </View>
            )}
         </ScrollView>

         <ImageViewing
            images={[{ uri: `${ConstEnv.url_storage}/files/${chooseFile?.idStorage}` }]}
            imageIndex={0}
            visible={preview}
            onRequestClose={() => setPreview(false)}
            doubleTapToZoomEnabled
            HeaderComponent={() => (
               <View style={Styles.headerModalViewImg}>
                  <Pressable onPress={() => setPreview(false)} accessibilityRole="button">
                     <Text style={[Styles.textWhite, Styles.font26]}>✕</Text>
                  </Pressable>
                  <Pressable
                     onPress={() => chooseFile && openFile(chooseFile)}
                     accessibilityRole="button"
                     disabled={loadingOpen}
                  >
                     <Text style={[Styles.font26, { color: loadingOpen ? 'gray' : 'white' }]}>⋯</Text>
                  </Pressable>
               </View>
            )}
            FooterComponent={() => (
               <View style={[Styles.pb20, Styles.ph16, Styles.alignCenter]}>
                  <Text style={[Styles.textWhite, Styles.font16]}>{chooseFile?.name}.{chooseFile?.extension}</Text>
               </View>
            )}
         />
      </SafeAreaView>
   )
}
