import React, { memo, useMemo, useState, useEffect, useCallback, useRef } from 'react'
import { Block, ConfirmModal, Text, Toast, VideoBox } from '@share/components'
import Img from '@share/components/Img'
import { Ionicons } from '@expo/vector-icons'
import { Dimensions, FlatList, TextInput, RefreshControl, ActivityIndicator } from 'react-native'
import { LinearGradient } from 'expo-linear-gradient'
import Animated, { Easing, useAnimatedStyle, useSharedValue, withRepeat, withTiming } from 'react-native-reanimated'

import { router, useRouter } from 'expo-router'
import { IOS_UNIVERSAL_LINK } from '@/app.constants'
import { FlashList } from '@shopify/flash-list'
import { screenHeight, screenWidth } from '@/utils'
import { cn } from '@/utils/cn'
import { useAuth } from '@/hooks/core/use-auth'
import { useUserBalance } from '@/hooks/core/use-user-balance'
import { useTemplates } from '@/hooks/data/use-templates'
import { usePublicTemplates } from '@/hooks/data/use-public-templates'
import { useFavoriteTemplates } from '@/hooks/data/use-favorite-templates'
import type { GetUserFavoritesResponse } from '@repo/sdk'
import { useAigcTask } from '@/hooks/actions/use-aigc-task'
import { useTemplateInteraction } from '@/hooks/actions/use-template-interaction'

const BACKGROUND_VIDEOS = [
  'https://cdn.roasmax.cn/material/b46f380532e14cf58dd350dbacc7c34a.mp4',
  'https://cdn.roasmax.cn/material/992e6c5d940c42feb71c27e556b754c0.mp4',
  'https://cdn.roasmax.cn/material/e4947477843f4067be7c37569a33d17b.mp4',
]

type MediaItem = {
  id: string
  type: 'image' | 'video'
  url: string
  poster?: string
  likeCount: number
}
type ActiveTab = 'gen' | '' | 'new' | 'like'

/** =========================
 * Small memo components
 * ========================= */

type BannerProps = { bgVideo: string }
const Banner = memo<BannerProps>(function Banner({ bgVideo }) {
  return (
    <Block className="absolute inset-0 bottom-0 left-0 right-0 top-0 z-[0] overflow-hidden">
      {/* <VideoBox url={bgVideo} style={{ width: screenWidth, height: screenHeight }} /> */}
      <Img src={bgVideo} style={{ width: screenWidth, height: screenHeight }} />
    </Block>
  )
})

type SearchOverlayProps = {
  isOpen: boolean
  searchText?: string
  onChange?: (v: string) => void
  onClose: () => void
  onSearch: (v: string) => void
}
const SearchOverlay = memo<SearchOverlayProps>(function SearchOverlay({ isOpen, onChange, onClose, onSearch }) {
  const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
  const [searchText, setSearchText] = useState('')
  const handleTextChange = (text: string) => {
    setSearchText(text)
    onChange && onChange(text)

    if (timerRef.current) {
      clearTimeout(timerRef.current)
    }

    timerRef.current = setTimeout(() => {
      onSearch(text)
    }, 2000)
  }

  useEffect(() => {
    // 删除定时器
    return () => {
      if (timerRef.current) {
        clearTimeout(timerRef.current)
      }
    }
  }, [])

  if (!isOpen) return null
  return (
    <Block className="absolute left-0 right-0 top-0 z-50 mt-[24px] flex-row items-center gap-[8px] px-[20px]">
      <Block
        className="flex-1 flex-row items-center border-[3px] border-black bg-white px-[12px] shadow-[4px_4px_0px_#000]"
        style={{ height: 48, transform: [{ skewX: '-6deg' }] }}
      >
        <Ionicons name="search" size={20} color="black" style={{ marginRight: 8 }} />
        <TextInput
          autoFocus
          value={searchText}
          onChangeText={handleTextChange}
          placeholder="搜索作品 / 用户..."
          placeholderTextColor="#9CA3AF"
          style={{
            flex: 1,
            fontSize: 14,
            fontWeight: 'bold',
            color: 'black',
          }}
        />
      </Block>
      <Block
        onClick={onClose}
        className="items-center justify-center border-[3px] border-black bg-[#FFE500] shadow-[4px_4px_0px_#000]"
        style={{ width: 48, height: 48, transform: [{ skewX: '-6deg' }] }}
      >
        <Ionicons name="close" size={24} color="black" style={{ transform: [{ skewX: '6deg' }] }} />
      </Block>

      <Block
        className="items-center justify-center border-[3px] border-black bg-[#FFE500] shadow-[4px_4px_0px_#000]"
        style={{ width: 48, height: 48, transform: [{ skewX: '-6deg' }] }}
      >
        <Text>登出</Text>
      </Block>
    </Block>
  )
})

type GooActionsProps = {
  gooPoints: number
  onAddGoo: () => void
  onOpenSearch: () => void
}
const GooActions = memo<GooActionsProps>(function GooActions({ gooPoints, onAddGoo, onOpenSearch }) {
  return (
    <Block>
      <Block className="mt-[12px] flex-row items-center gap-[8px]">
        <Block
          onClick={onAddGoo}
          className="flex-row items-center gap-[4px] rounded-full border-[3px] border-white bg-black px-[12px] py-[8px] shadow-[3px_3px_0px_rgba(0,0,0,0.5)]"
        >
          <Text className="text-[12px] font-black italic text-[#FFE500]">{gooPoints} Goo</Text>
          <Ionicons name="add" size={12} color="#FFE500" style={{ fontWeight: 'bold' }} />
        </Block>

        <Block
          onClick={onOpenSearch}
          className="h-[48px] w-[48px] items-center justify-center rounded-full border-[3px] border-black bg-white shadow-[4px_4px_0px_#000]"
        >
          <Ionicons name="search" size={22} color="black" />
        </Block>
      </Block>
    </Block>
  )
})

type HeroCircleProps = {
  selectedItem: MediaItem | null
  onQuickGen: () => void
  rightSlot: React.ReactNode
}
const HeroCircle = memo<HeroCircleProps>(function HeroCircle({ selectedItem, onQuickGen, rightSlot }) {
  if (!selectedItem) {
    return (
      <Block className="relative z-[10] mt-[12px] items-center justify-between">
        <Block className="relative flex-row justify-between">
          <Block className="relative z-[10] mt-[20px] h-[224px] w-[224px] items-center justify-center rounded-full border-[4px] border-black bg-white/20 shadow-deep-black">
            <Text className="text-[14px] font-bold text-white/60">加载中...</Text>
          </Block>
          {rightSlot}
        </Block>
      </Block>
    )
  }

  return (
    <Block className="relative z-[10] mt-[12px] items-center justify-between">
      <Block className="relative flex-row justify-between">
        <Block className="relative z-[10] mt-[20px] h-[224px] w-[224px] rounded-full border-[4px] border-black bg-white shadow-deep-black">
          <Block className="relative h-full w-full overflow-hidden rounded-full bg-black">
            {selectedItem.type === 'video' ? (
              <VideoBox url={selectedItem.url} style={{ height: 216, width: 216, borderRadius: 108 }} />
            ) : (
              <Img src={selectedItem.url} className="h-full w-full" />
            )}

            <Block className="absolute inset-[0px]">
              <LinearGradient
                colors={['rgba(255,255,255,0.3)', 'transparent']}
                start={{ x: 0, y: 0 }}
                end={{ x: 1, y: 1 }}
                style={{ position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, borderRadius: 9999 }}
              />
            </Block>
          </Block>

          <Block className="pointer-events-none absolute inset-[0px] rounded-full border-[2px] border-black/10" />

          <Block className="absolute bottom-[24px] left-[8px] z-[20] max-w-[100px] bg-black px-[12px] py-[4px] shadow-small-accent">
            <Text className="font-900 skew-x-[-12deg] text-[10px] italic text-white" numberOfLines={1} ellipsizeMode="tail">
              {selectedItem?.id}
            </Text>
          </Block>

          <Block
            onClick={onQuickGen}
            className="absolute bottom-[16px] right-[0px] z-[30] skew-x-[-6deg] flex-row items-center gap-[4px] border-[3px] border-black bg-accent px-[16px] py-[6px] shadow-medium-black"
          >
            <Ionicons name="flash" size={14} color="black" />
            <Text className="font-900 text-[12px] italic text-black">GET 同款</Text>
          </Block>
        </Block>

        {rightSlot}
      </Block>
    </Block>
  )
})

type FilterSectionProps = {
  activeTab: ActiveTab
  onChange: (t: ActiveTab) => void
}
const FilterSection = memo<FilterSectionProps>(function FilterSection({ activeTab, onChange }) {
  const tabs = useMemo(
    () => [
      { label: '最热', state: '' as const },
      { label: '最新', state: 'new' as const },
      { label: '喜欢', state: 'like' as const },
    ],
    [],
  )

  return (
    <Block className="mt-[12px] flex-row items-end justify-between">
      <Block className="flex-row gap-[8px]">
        {tabs.map(({ label, state }) => {
          const isActive = activeTab === state
          return (
            <Block
              key={state}
              onClick={() => onChange(state)}
              className={`border-[2px] border-black px-[16px] py-[4px] ${isActive ? 'bg-accent' : 'bg-white'}`}
              style={{
                transform: [{ skewX: '-6deg' }],
              }}
            >
              <Text className={`text-[10px] font-[900] italic ${isActive ? 'text-black' : 'text-gray-500'}`}>{label}</Text>
            </Block>
          )
        })}
      </Block>
    </Block>
  )
})

type GridItemProps = {
  item: MediaItem
  isSelected: boolean
  itemWidth: number
  onSelect: () => void
}
const GridItem = memo<GridItemProps>(function GridItem({ item, isSelected, itemWidth, onSelect }) {
  // console.log('item-------------', item);

  return (
    <Block onClick={onSelect} className="relative mb-[12px]">
      <Block
        className={`relative overflow-hidden border-[2px] ${isSelected ? 'border-accent' : 'border-black'}`}
        style={{
          transform: [{ skewX: '-6deg' }],
          height: itemWidth,
          width: itemWidth,
        }}
      >
        {/* {item.type === 'video' ? (
          <VideoBox url={item.url} style={{ height: itemWidth, width: itemWidth }} />
        ) : (
          <Img src={item.poster} className="h-full w-full" />
        )} */}
        {/* <Img src={item.poster} className="h-full w-full" /> */}

        <VideoBox url={item.url} style={{ height: itemWidth, width: itemWidth }} />

        {isSelected && <Block className="absolute inset-[0px] border-[3px] border-accent" />}

        <Block
          className={cn('absolute left-[0px] top-[0px] z-[20] border-b-[2px] border-r-[2px] border-black bg-black px-[6px] py-[2px]', {
            'bg-accent': isSelected,
          })}
        >
          <Text
            className={cn('font-900 text-[8px] text-white', {
              'text-black': isSelected,
            })}
          >
            {item.id}
          </Text>
        </Block>

        <Block
          className="absolute bottom-[0px] left-[0px] right-[0px] z-[20] items-end justify-between p-[4px] pt-[16px]"
          style={{ transform: [{ skewX: '6deg' }] }}
        >
          <LinearGradient
            colors={['rgba(0,0,0,0.8)', 'transparent']}
            start={{ x: 0, y: 1 }}
            end={{ x: 0, y: 0 }}
            style={{ position: 'absolute', left: 0, right: 0, top: 0, bottom: 0 }}
          />

          <Block className="w-full flex-1 flex-row items-center justify-between px-[4px]">
            <Block className="">
              <Text className="font-900 max-w-[40px] skew-x-[-6deg] text-[7px] italic text-white" numberOfLines={1}>
                {item.id}
              </Text>
            </Block>
            <Block className="skew-x-[-6deg] flex-row items-center gap-[2px]">
              <Ionicons name="heart" size={10} color="#FF0000" />
              <Text className="font-900 text-[8px] italic text-white">{item.likeCount}</Text>
            </Block>
          </Block>
        </Block>
      </Block>
    </Block>
  )
})

/** =========================
 * Entry page
 * ========================= */

export default function Sync() {
  const { user, isAuthenticated } = useAuth()
  const { balance, loading: balanceLoading, load: loadBalance } = useUserBalance()
  const { data: templatesData, loading: templatesLoading, execute: loadTemplates } = useTemplates()
  const { data: publicTemplatesData, loading: publicTemplatesLoading, execute: loadPublicTemplates } = usePublicTemplates()
  const { data: favoritesData, loading: favoritesLoading, execute: loadFavorites } = useFavoriteTemplates()
  const { submitTask, startPolling } = useAigcTask()

  const [searchText, setSearchText] = useState('')
  const [isSearchOpen, setIsSearchOpen] = useState(false)
  const [activeTab, setActiveTab] = useState<ActiveTab>('')

  const [page, setPage] = useState(1)
  const [hasMore, setHasMore] = useState(true)
  const [refreshing, setRefreshing] = useState(false)
  const [loadingMore, setLoadingMore] = useState(false)
  const [allItems, setAllItems] = useState<MediaItem[]>([])
  const isLoadingRef = useRef(false)

  const onAddGoo = useCallback(() => {
    router.push('/pointList')
  }, [])

  const transformTemplateToMediaItem = useCallback((template: any): MediaItem => {
    const isVideo = template.previewUrl?.includes('.mp4')
    return {
      id: template.id,
      type: (isVideo ? 'video' : 'image') as 'video' | 'image',
      url: isVideo ? template.previewUrl : template.coverImageUrl || template.previewUrl,
      poster: isVideo ? template.coverImageUrl : undefined,
      likeCount: template.likeCount || 0,
    }
  }, [])

  const galleryItems = useMemo<MediaItem[]>(() => allItems, [allItems])

  const [selectedItem, setSelectedItem] = useState<MediaItem | null>(null)

  useEffect(() => {
    if (galleryItems.length > 0 && !selectedItem) {
      setSelectedItem(galleryItems[0])
    }
  }, [galleryItems, selectedItem])

  const [bgVideo] = useState(() => BACKGROUND_VIDEOS[Math.floor(Math.random() * BACKGROUND_VIDEOS.length)])

  const outerRotate = useSharedValue(0)

  useEffect(() => {
    if (isAuthenticated && user?.id) {
      loadBalance(user.id)
    }
  }, [isAuthenticated, user?.id])

  // Tab 切换时重置并加载数据
  useEffect(() => {
    setPage(1)
    setHasMore(true)
    setAllItems([])

    const initialLoad = async () => {
      if (isLoadingRef.current) return
      isLoadingRef.current = true
      setRefreshing(true)
      try {
        let newItems: MediaItem[] = []
        const limit = 20

        if (activeTab === 'like') {
          if (!isAuthenticated) {
            setHasMore(false)
            return
          }
          const { data, error } = await loadFavorites({ limit, page: 1 })
          if (error || !data?.favorites) {
            setHasMore(false)
            return
          }
          newItems = data.favorites.filter((fav: GetUserFavoritesResponse['favorites'][number]) => fav.template && !fav.template.isDeleted).map((fav: GetUserFavoritesResponse['favorites'][number]) => transformTemplateToMediaItem(fav.template!))
        } else if (activeTab === 'new') {
          if (isAuthenticated) {
            const { data, error } = await loadTemplates({ limit, page: 1, sortBy: 'createdAt', sortOrder: 'desc' })
            if (error || !data?.templates) {
              setHasMore(false)
              return
            }
            newItems = data.templates.map(transformTemplateToMediaItem)
          } else {
            const { data, error } = await loadPublicTemplates({ limit, sortBy: 'createdAt', sortOrder: 'desc' })
            if (error || !data?.templates) {
              setHasMore(false)
              return
            }
            newItems = data.templates.map(transformTemplateToMediaItem)
            setHasMore(false)
          }
        } else {
          if (isAuthenticated) {
            const { data, error } = await loadTemplates({ limit, page: 1, sortBy: 'likeCount', sortOrder: 'desc' })
            if (error || !data?.templates) {
              setHasMore(false)
              return
            }
            newItems = data.templates.map(transformTemplateToMediaItem)
          } else {
            const { data, error } = await loadPublicTemplates({ limit, sortBy: 'likeCount', sortOrder: 'desc' })
            if (error || !data?.templates) {
              setHasMore(false)
              return
            }
            newItems = data.templates.map(transformTemplateToMediaItem)
            setHasMore(false)
          }
        }

        if (newItems.length < limit) {
          setHasMore(false)
        }

        setAllItems(newItems)
      } catch (error) {
        console.error('Failed to load data:', error)
        setHasMore(false)
      } finally {
        isLoadingRef.current = false
        setRefreshing(false)
      }
    }

    initialLoad()
  }, [activeTab, isAuthenticated])

  const loadData = useCallback(
    async (pageNum: number, isRefresh: boolean = false) => {
      if (!isRefresh && !hasMore) return
      if (loadingMore || refreshing || isLoadingRef.current) return

      isLoadingRef.current = true

      if (isRefresh) {
        setRefreshing(true)
      } else {
        setLoadingMore(true)
      }

      try {
        let newItems: MediaItem[] = []
        const limit = 20

        if (activeTab === 'like') {
          if (!isAuthenticated) {
            setHasMore(false)
            return
          }
          const { data, error } = await loadFavorites({ limit, page: pageNum })
          if (error || !data?.favorites) {
            setHasMore(false)
            return
          }
          newItems = data.favorites.filter((fav: GetUserFavoritesResponse['favorites'][number]) => fav.template && !fav.template.isDeleted).map((fav: GetUserFavoritesResponse['favorites'][number]) => transformTemplateToMediaItem(fav.template!))
        } else if (activeTab === 'new') {
          if (!isAuthenticated) {
            setHasMore(false)
            return
          }
          const { data, error } = await loadTemplates({ limit, page: pageNum, sortBy: 'createdAt', sortOrder: 'desc' })
          if (error || !data?.templates) {
            setHasMore(false)
            return
          }
          newItems = data.templates.map(transformTemplateToMediaItem)
        } else {
          if (!isAuthenticated) {
            setHasMore(false)
            return
          }
          const { data, error } = await loadTemplates({ limit, page: pageNum, sortBy: 'likeCount', sortOrder: 'desc' })
          if (error || !data?.templates) {
            setHasMore(false)
            return
          }
          newItems = data.templates.map(transformTemplateToMediaItem)
        }

        if (newItems.length < limit) {
          setHasMore(false)
        }

        if (isRefresh) {
          setAllItems(newItems)
        } else {
          setAllItems((prev) => [...prev, ...newItems])
        }
      } catch (error) {
        console.error('Failed to load data:', error)
        setHasMore(false)
      } finally {
        isLoadingRef.current = false
        setRefreshing(false)
        setLoadingMore(false)
      }
    },
    [activeTab, isAuthenticated, hasMore, loadingMore, refreshing, loadTemplates, loadPublicTemplates, loadFavorites, transformTemplateToMediaItem],
  )

  const handleRefresh = useCallback(() => {
    setPage(1)
    setHasMore(true)
    loadData(1, true)
  }, [loadData])

  const handleLoadMore = useCallback(() => {
    if (!hasMore || loadingMore || refreshing || isLoadingRef.current) return
    const nextPage = page + 1
    setPage(nextPage)
    loadData(nextPage, false)
  }, [page, hasMore, loadingMore, refreshing, loadData])

  useEffect(() => {
    outerRotate.value = withRepeat(withTiming(360, { duration: 12000, easing: Easing.linear }), -1, false)
  }, [])

  const handleQuickGen = useCallback(async () => {
    if (!isAuthenticated) {
      Toast.show({ title: '请先登录' })
      return
    }

    if (!selectedItem) {
      Toast.show({ title: '请先选择一个模板' })
      return
    }

    const cost = 2

    if (balance < cost) {
      Toast.show({ title: '余额不足，请充值' })
      return
    }

    Toast.showModal(
      <ConfirmModal
        content={
          <Text className="text-[14px] font-bold leading-relaxed text-gray-800">
            生成同款风格将消耗 <Text className="mx-[4px] text-[20px] font-black italic text-[#e61e25]">{cost} Goo</Text> 算力。
          </Text>
        }
        onConfirm={async () => {
          Toast.hideModal()

          const { taskId, error } = await submitTask({
            model_name: 'default',
            prompt: `生成与 ${selectedItem.id} 相似的内容`,
            img_url: selectedItem.url,
          })

          if (error) {
            Toast.show({ title: `提交失败: ${error.message}` })
            return
          }

          if (taskId) {
            Toast.show({ title: '任务提交成功，正在生成中...' })
            startPolling(
              taskId,
              (result) => {
                Toast.show({ title: '生成成功！' })
                if (user?.id) loadBalance(user.id)
              },
              (error) => {
                Toast.show({ title: `生成失败: ${error.message}` })
              },
            )
          }
        }}
        onCancel={() => Toast.hideModal()}
      />,
      {},
    )
  }, [isAuthenticated, balance, selectedItem, submitTask, startPolling, user?.id, loadBalance])

  const openSearch = useCallback(() => setIsSearchOpen(true), [])
  const closeSearch = useCallback(() => {
    setIsSearchOpen(false)
    setSearchText('')
  }, [])

  // keep for parity with your original file (even if not actively used yet)
  const outerAnimatedStyle = useAnimatedStyle(() => ({
    transform: [{ rotate: `${outerRotate.value}deg` }],
  }))

  const { width: winW } = Dimensions.get('window')
  const itemWidth = useMemo(() => Math.floor((winW - 24 - 12 * 2) / 3), [winW])

  const renderGridItem = useCallback(
    ({ item }: { item: MediaItem }) => (
      <GridItem item={item} isSelected={selectedItem?.id === item.id} itemWidth={itemWidth} onSelect={() => setSelectedItem(item)} />
    ),
    [selectedItem, itemWidth],
  )

  const renderListFooter = useCallback(() => {
    if (!loadingMore) return null
    return (
      <Block className="items-center py-[20px]">
        <ActivityIndicator size="small" color="#FFE500" />
      </Block>
    )
  }, [loadingMore])

  const renderListEmpty = useCallback(() => {
    if (activeTab === 'like' && !isAuthenticated) {
      return (
        <Block className="mt-[40px] items-center justify-center gap-[16px] py-[60px]">
          <Block className="h-[80px] w-[80px] items-center justify-center rounded-full border-[4px] border-white/20 bg-white/10">
            <Ionicons name="heart-outline" size={40} color="rgba(255,255,255,0.6)" />
          </Block>
          <Text className="text-[16px] font-bold text-white/80">查看您收藏的模板</Text>
          <Text className="text-[12px] text-white/50">登录后即可查看和管理收藏</Text>
          <Block
            onClick={() => router.push('/auth')}
            className="mt-[12px] flex-row items-center gap-[8px] border-[3px] border-white bg-accent px-[32px] py-[12px] shadow-[4px_4px_0px_rgba(255,255,255,0.2)]"
            style={{ transform: [{ skewX: '-6deg' }] }}
          >
            <Ionicons name="flash" size={16} color="black" style={{ transform: [{ skewX: '6deg' }] }} />
            <Text className="font-900 text-[14px] italic text-black" style={{ transform: [{ skewX: '6deg' }] }}>
              立即登录
            </Text>
          </Block>
        </Block>
      )
    }
    return (
      <Block className="mt-[12px] items-center justify-center py-[40px]">
        <Text className="text-[14px] font-bold text-white/60">暂无内容</Text>
      </Block>
    )
  }, [activeTab, isAuthenticated])

  const handleSearch = useCallback((text: string) => {
    console.log('Search for:', text)
    // Implement your search logic here
  }, [])

  return (
    <Block className="relative flex-1 flex-col overflow-visible bg-black px-[12px]">
      <Banner bgVideo={bgVideo} />

      <HeroCircle
        selectedItem={selectedItem}
        onQuickGen={handleQuickGen}
        rightSlot={<GooActions gooPoints={balance} onAddGoo={onAddGoo} onOpenSearch={openSearch} />}
      />

      <FilterSection activeTab={activeTab} onChange={setActiveTab} />

      <FlashList
        data={galleryItems}
        renderItem={renderGridItem}
        keyExtractor={(item) => item.id}
        numColumns={3}
        contentContainerStyle={{ marginTop: 12, paddingBottom: 200 }}
        showsVerticalScrollIndicator={false}
        refreshControl={<RefreshControl refreshing={refreshing} onRefresh={handleRefresh} tintColor="#FFE500" colors={['#FFE500']} />}
        onEndReached={handleLoadMore}
        onEndReachedThreshold={0.5}
        ListFooterComponent={renderListFooter}
        ListEmptyComponent={renderListEmpty}
      />

      <SearchOverlay isOpen={isSearchOpen} onClose={() => setIsSearchOpen(false)} onSearch={handleSearch} />
    </Block>
  )
}
