import { ButtonForm } from "@/components/buttonForm"
import DrawerBottom from "@/components/drawerBottom"
import ImageUser from "@/components/imageNew"
import ImageWithLabel from "@/components/imageWithLabel"
import InputSearch from "@/components/inputSearch"
import Text from "@/components/Text"
import { ConstEnv } from "@/constants/ConstEnv"
import Styles from "@/constants/Styles"
import { apiGetDivision, apiGetDivisionMember, apiGetUser } from "@/lib/api"
import { setMemberChoose } from "@/lib/memberChoose"
import { useAuthSession } from "@/providers/AuthProvider"
import { useTheme } from "@/providers/ThemeProvider"
import { AntDesign, Ionicons } from "@expo/vector-icons"
import { useEffect, useState } from "react"
import { ActivityIndicator, Pressable, ScrollView, View } from "react-native"
import { useDispatch, useSelector } from "react-redux"

type Member = { idUser: string; name: string; img: string }

type DivisionItem = {
   id: string
   name: string
   expanded: boolean
   membersLoaded: boolean
   members: Member[]
}

type Props = {
   open: boolean
   close: (value: boolean) => void
   idGroup: string
}

export default function ModalSelectMemberByDivision({ open, close, idGroup }: Props) {
   const { token, decryptToken } = useAuthSession()
   const { colors } = useTheme()
   const dispatch = useDispatch()
   const entitiesMember = useSelector((state: any) => state.memberChoose)

   const [divisions, setDivisions] = useState<DivisionItem[]>([])
   const [selectMember, setSelectMember] = useState<Member[]>([])
   const [search, setSearch] = useState('')
   const [loadingDivisions, setLoadingDivisions] = useState(false)
   const [loadingIds, setLoadingIds] = useState<string[]>([])
   const [searchResults, setSearchResults] = useState<any[]>([])
   const [loadingSearch, setLoadingSearch] = useState(false)

   async function loadDivisions() {
      if (!idGroup) return
      setLoadingDivisions(true)
      try {
         const hasil = await decryptToken(String(token?.current))
         const response = await apiGetDivision({ user: hasil, search: '', group: idGroup, active: 'true', kategori: 'semua', page: 1 })
         const divisionList: DivisionItem[] = (response.data ?? []).map((d: any) => ({
            id: d.id, name: d.name, expanded: false, membersLoaded: false, members: []
         }))
         const withMembers = await Promise.all(
            divisionList.map(async (d) => {
               try {
                  const res = await apiGetDivisionMember({ user: hasil, id: d.id, search: '' })
                  const members: Member[] = (res.data ?? []).map((m: any) => ({ idUser: m.idUser, name: m.name, img: m.img }))
                  return { ...d, members, membersLoaded: true }
               } catch {
                  return { ...d, membersLoaded: true }
               }
            })
         )
         setDivisions(withMembers)
      } catch { setDivisions([]) }
      finally { setLoadingDivisions(false) }
   }

   async function fetchMembers(divisionId: string): Promise<Member[]> {
      setLoadingIds(prev => [...prev, divisionId])
      try {
         const hasil = await decryptToken(String(token?.current))
         const response = await apiGetDivisionMember({ user: hasil, id: divisionId, search: '' })
         const members: Member[] = (response.data ?? []).map((m: any) => ({ idUser: m.idUser, name: m.name, img: m.img }))
         setDivisions(prev => prev.map(d =>
            d.id === divisionId ? { ...d, members, membersLoaded: true } : d
         ))
         return members
      } catch { return [] }
      finally { setLoadingIds(prev => prev.filter(id => id !== divisionId)) }
   }

   async function searchUsers(query: string) {
      setLoadingSearch(true)
      try {
         const hasil = await decryptToken(String(token?.current))
         const response = await apiGetUser({ user: hasil, active: 'true', search: query, group: idGroup })
         setSearchResults((response.data ?? []).filter((i: any) => i.idUserRole !== 'supadmin'))
      } catch { setSearchResults([]) }
      finally { setLoadingSearch(false) }
   }

   useEffect(() => {
      if (open) { loadDivisions(); setSelectMember(entitiesMember) }
   }, [open])

   useEffect(() => {
      if (!open) return
      if (search) {
         searchUsers(search)
      } else {
         setSearchResults([])
         loadDivisions()
      }
   }, [search])

   async function handleTapDivision(division: DivisionItem) {
      let members = division.members
      if (!division.membersLoaded) members = await fetchMembers(division.id)
      setDivisions(prev => prev.map(d =>
         d.id === division.id ? { ...d, expanded: true, members, membersLoaded: true } : d
      ))
      const allSelected = members.length > 0 && members.every(m =>
         selectMember.some(s => s.idUser === m.idUser)
      )
      if (allSelected) {
         setSelectMember(prev => prev.filter(s => !members.some(m => m.idUser === s.idUser)))
      } else {
         const existingIds = new Set(selectMember.map(s => s.idUser))
         setSelectMember(prev => [...prev, ...members.filter(m => !existingIds.has(m.idUser))])
      }
   }

   async function handleToggleExpand(divisionId: string) {
      const division = divisions.find(d => d.id === divisionId)!
      if (!division.membersLoaded && !division.expanded) await fetchMembers(divisionId)
      setDivisions(prev => prev.map(d =>
         d.id === divisionId ? { ...d, expanded: !d.expanded } : d
      ))
   }

   function handleToggleMember(member: Member) {
      if (selectMember.some(s => s.idUser === member.idUser)) {
         setSelectMember(prev => prev.filter(s => s.idUser !== member.idUser))
      } else {
         setSelectMember(prev => [...prev, member])
      }
   }

   function handleConfirm() {
      dispatch(setMemberChoose(selectMember))
      handleClose()
   }

   function handleClose() {
      setDivisions([])
      setSelectMember([])
      setSearch('')
      close(false)
   }

   return (
      <DrawerBottom animation="none" isVisible={open} setVisible={handleClose} title="Pilih Anggota" height={90}>
         <InputSearch onChange={setSearch} value={search} bg="transparent" />
         {selectMember.length > 0
            ? (
               <View>
                  <ScrollView horizontal style={[Styles.mb10, Styles.pv10]} showsHorizontalScrollIndicator={false}>
                     {selectMember.map((item, index) => (
                        <ImageWithLabel
                           key={index}
                           label={item.name}
                           src={`${ConstEnv.url_storage}/files/${item.img}`}
                           onClick={() => handleToggleMember(item)}
                        />
                     ))}
                  </ScrollView>
               </View>
            )
            : (
               <Text style={[Styles.textDefault, { color: colors.dimmed, textAlign: 'center' }, Styles.pv05]}>
                  Tidak ada member yang dipilih
               </Text>
            )
         }
         <ScrollView showsVerticalScrollIndicator={false}>
            <View>
               {search ? (
                  loadingSearch ? (
                     <ActivityIndicator color={colors.tabActive} style={{ marginTop: 20 }} />
                  ) : searchResults.length > 0 ? (
                     searchResults.map((item, idx) => (
                        <Pressable
                           key={idx}
                           style={[Styles.itemSelectModal, { borderColor: colors.icon + '20' }]}
                           onPress={() => handleToggleMember({ idUser: item.id, name: item.name, img: item.img })}
                        >
                           <View style={Styles.rowItemsCenter}>
                              <ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} border />
                              <Text style={[Styles.textDefault, Styles.ml10]}>{item.name}</Text>
                           </View>
                           {selectMember.some(s => s.idUser === item.id) && (
                              <AntDesign name="check" size={18} color={colors.tabActive} />
                           )}
                        </Pressable>
                     ))
                  ) : (
                     <Text style={[Styles.textDefault, { textAlign: 'center', color: colors.dimmed, marginTop: 20 }]}>
                        Tidak ada hasil
                     </Text>
                  )
               ) : loadingDivisions ? (
                  <ActivityIndicator color={colors.tabActive} style={{ marginTop: 20 }} />
               ) : divisions.length > 0 ? (
                  divisions.map((division) => {
                     const selectedCount = division.members.filter(m =>
                        selectMember.some(s => s.idUser === m.idUser)
                     ).length
                     const allSelected = division.membersLoaded && division.members.length > 0
                        && selectedCount === division.members.length
                     const someSelected = selectedCount > 0 && !allSelected
                     const isLoadingThis = loadingIds.includes(division.id)

                     return (
                        <View key={division.id}>
                           <Pressable
                              style={[Styles.itemSelectModal, { borderColor: colors.icon + '20' }]}
                              onPress={() => handleTapDivision(division)}
                           >
                              <View style={Styles.flex1}>
                                 <Text style={[Styles.textDefaultSemiBold, { color: colors.text }]}>{division.name}</Text>
                                 {division.membersLoaded && (
                                    <Text style={[Styles.textSmallSemiBold, { color: colors.dimmed }]}>
                                       {selectedCount > 0
                                          ? `${selectedCount} dari ${division.members.length} dipilih`
                                          : `${division.members.length} anggota`}
                                    </Text>
                                 )}
                              </View>
                              {isLoadingThis ? (
                                 <ActivityIndicator size="small" color={colors.dimmed} />
                              ) : allSelected ? (
                                 <AntDesign name="checkcircle" size={18} color={colors.tabActive} />
                              ) : someSelected ? (
                                 <AntDesign name="checkcircleo" size={18} color={colors.tabActive} />
                              ) : null}
                              <Pressable
                                 onPress={() => handleToggleExpand(division.id)}
                                 style={{ paddingLeft: 10 }}
                                 hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
                              >
                                 <Ionicons
                                    name={division.expanded ? "chevron-up" : "chevron-down"}
                                    size={16}
                                    color={colors.dimmed}
                                 />
                              </Pressable>
                           </Pressable>

                           {division.expanded && division.members.map((member, idx) => (
                              <Pressable
                                 key={idx}
                                 style={[Styles.itemSelectModal, { borderColor: colors.icon + '15' }]}
                                 onPress={() => handleToggleMember(member)}
                              >
                                 <View style={Styles.rowItemsCenter}>
                                    <ImageUser src={`${ConstEnv.url_storage}/files/${member.img}`} border />
                                    <Text style={[Styles.textDefault, Styles.ml10]}>{member.name}</Text>
                                 </View>
                                 {selectMember.some(s => s.idUser === member.idUser) && (
                                    <AntDesign name="check" size={18} color={colors.tabActive} />
                                 )}
                              </Pressable>
                           ))}
                        </View>
                     )
                  })
               ) : (
                  <Text style={[Styles.textDefault, { textAlign: 'center', color: colors.dimmed, marginTop: 20 }]}>
                     Tidak ada divisi
                  </Text>
               )}
            </View>
         </ScrollView>

         <ButtonForm
            onPress={handleConfirm}
            text="PILIH MEMBER"
            disabled={selectMember.length === 0}
         />
      </DrawerBottom>
   )
}
