import { useEffect, useRef, useState } from 'react'
import Taro, { useRouter } from '@tarojs/taro'
import { Image, ScrollView, Text, View } from '@tarojs/components'
import { useSystemLayout } from '@/hooks/useSystemLayout'
import Icon from '@/components/ui/Icon'
import ProfileHero from '@/features/profile/components/ProfileHero'
import StatsRow from '@/features/profile/components/StatsRow'
import PostCard from '@/features/feed/components/PostCard'
import ToastOverlay from '@/components/feedback/ToastOverlay'
import { getProfile } from '@/services/profile.service'
import { getUserPosts, setPostLike } from '@/services/feed.service'
import { useToast } from '@/hooks/useToast'
import { cachePost, onPostLike } from '@/store/dataBus'
import { ensureProfileReady } from '@/store/session.store'
import type { Pet, Post, UserProfile } from '@/types/domain'
import './index.scss'

const PAGE_SIZE = 20

function mergePosts(current: Post[], incoming: Post[]): Post[] {
  const seen = new Set(current.map(post => post._id))
  return [...current, ...incoming.filter(post => !seen.has(post._id))]
}

export default function UserProfilePage() {
  const { statusBarHeight, safeBottom } = useSystemLayout()
  const router = useRouter()
  const userId = router.params.userId || ''
  const [user, setUser] = useState<UserProfile | null>(null)
  const [pets, setPets] = useState<Pet[]>([])
  const [posts, setPosts] = useState<Post[]>([])
  const [loading, setLoading] = useState(true)
  const [loadingMore, setLoadingMore] = useState(false)
  const [nextCursor, setNextCursor] = useState('')
  const toast = useToast(480)
  const postsRef = useRef<Post[]>([])
  const pendingLikeIds = useRef(new Set<string>())

  useEffect(() => {
    postsRef.current = posts
  }, [posts])

  useEffect(() => onPostLike(({ postId, liked, likes }) => {
    setPosts(current => current.map(post => (
      post._id === postId
        ? post.likedByMe === liked && post.counts.likes === likes
          ? post
          : { ...post, likedByMe: liked, counts: { ...post.counts, likes } }
        : post
    )))
  }), [])

  const loadPosts = (append = false, cursor = '') => {
    if (!userId) return
    if (append) setLoadingMore(true)
    getUserPosts({ authorId: userId, cursor, pageSize: PAGE_SIZE })
      .then(result => {
        setPosts(current => (append ? mergePosts(current, result.list) : result.list))
        setNextCursor(result.nextCursor || '')
      })
      .finally(() => {
        if (append) setLoadingMore(false)
      })
  }

  useEffect(() => {
    if (!userId) {
      setLoading(false)
      return
    }

    setLoading(true)
    Promise.all([
      getProfile(userId),
      getUserPosts({ authorId: userId, pageSize: PAGE_SIZE })
    ])
      .then(([profile, postResult]) => {
        setUser(profile.user)
        setPets(profile.pets)
        setPosts(postResult.list)
        setNextCursor(postResult.nextCursor || '')
      })
      .finally(() => setLoading(false))
  }, [userId])

  const loadMore = () => {
    if (loading || loadingMore || !nextCursor) return
    loadPosts(true, nextCursor)
  }

  const likePost = async (postId: string) => {
    if (!(await ensureProfileReady())) return
    if (pendingLikeIds.current.has(postId)) return
    const previousPost = postsRef.current.find(post => post._id === postId)
    if (!previousPost) return

    const likedByMe = !previousPost.likedByMe
    const likes = Math.max(0, previousPost.counts.likes + (likedByMe ? 1 : -1))
    pendingLikeIds.current.add(postId)
    if (likedByMe) toast.show()
    setPosts(current => current.map(post => (
      post._id === postId
        ? { ...post, likedByMe, counts: { ...post.counts, likes } }
        : post
    )))

    try {
      const result = await setPostLike(postId, likedByMe)
      setPosts(current => current.map(post => (
        post._id === postId
          ? { ...post, likedByMe: result.liked, counts: { ...post.counts, likes: result.likes } }
          : post
      )))
    } catch {
      setPosts(current => current.map(post => (
        post._id === postId
          ? {
            ...post,
            likedByMe: previousPost.likedByMe,
            counts: { ...post.counts, likes: previousPost.counts.likes }
          }
          : post
      )))
      Taro.showToast({ title: '点赞失败，请重试', icon: 'none' })
    } finally {
      pendingLikeIds.current.delete(postId)
    }
  }

  const openChat = async () => {
    if (!user) return
    if (!(await ensureProfileReady())) return
    Taro.navigateTo({
      url: `/pages/chat/index?targetUserId=${user._id}&title=${encodeURIComponent(user.nickname)}`
    })
  }

  return (
    <View className='user-profile'>
      <View className='user-profile__nav' style={{ paddingTop: `${statusBarHeight}px` }}>
        <View className='user-profile__nav-row'>
          <View className='user-profile__back' onClick={() => Taro.navigateBack()}>
            <Icon name='chev' size={22} className='user-profile__back-icon' />
          </View>
          <Text className='user-profile__title'>{user?.nickname || '个人主页'}</Text>
          <View className='user-profile__nav-spacer' />
        </View>
      </View>

      <ScrollView
        scrollY
        className='user-profile__scroll'
        enhanced
        showScrollbar={false}
        lowerThreshold={120}
        onScrollToLower={loadMore}
      >
        {user ? (
          <>
            <ProfileHero user={user} />
            <StatsRow stats={user.stats} />
            <View className='user-profile__actions'>
              <View className='user-profile__primary' onClick={openChat}>
                发消息
              </View>
            </View>

            <View className='user-profile__section'>
              <Text className='user-profile__section-title'>毛孩子 · {pets.length}</Text>
              <ScrollView scrollX showScrollbar={false} className='user-profile__pet-scroll'>
                <View className='user-profile__pet-list'>
                  {pets.map(pet => (
                    <View key={pet._id} className='user-profile__pet-card'>
                      <View className={`user-profile__pet-photo ${pet.photoUrl ? '' : pet.photoKey}`}>
                        {pet.photoUrl ? (
                          <Image className='user-profile__pet-img' src={pet.photoUrl} mode='aspectFill' />
                        ) : null}
                        <Text className='user-profile__pet-label'>{pet.species === 'cat' ? 'CAT' : 'DOG'}</Text>
                      </View>
                      <Text className='user-profile__pet-name'>{pet.name} · {pet.breed}</Text>
                      <Text className='user-profile__pet-meta'>{pet.ageText || '待完善'} · {pet.tags[0] || '待完善'}</Text>
                    </View>
                  ))}
                  {pets.length === 0 ? <Text className='user-profile__empty-small'>还没有公开的毛孩子</Text> : null}
                </View>
              </ScrollView>
            </View>

            <View className='user-profile__section'>
              <Text className='user-profile__section-title'>公开动态</Text>
            </View>
            <View className='user-profile__feed'>
              {posts.map(post => (
                <PostCard
                  key={post._id}
                  post={post}
                  onLike={likePost}
                  onOpen={id => {
                    cachePost(post)
                    Taro.navigateTo({ url: `/pages/post-detail/index?postId=${id}` })
                  }}
                />
              ))}
              {loading && posts.length === 0 ? (
                <Text className='user-profile__empty'>加载中…</Text>
              ) : !loading && posts.length === 0 ? (
                <Text className='user-profile__empty'>还没有公开动态</Text>
              ) : loadingMore ? (
                <Text className='user-profile__empty'>加载更多中…</Text>
              ) : posts.length > 0 && !nextCursor ? (
                <Text className='user-profile__empty'>暂时没有更多了</Text>
              ) : null}
            </View>
          </>
        ) : (
          <Text className='user-profile__empty'>{loading ? '加载中…' : '用户不存在'}</Text>
        )}
        <View style={{ height: `${Math.max(20, safeBottom)}px` }} />
      </ScrollView>
      <ToastOverlay visible={toast.visible} />
    </View>
  )
}
