package com.aiosman.ravenow.ui.index.tabs.search

import android.content.Context
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.cachedIn
import androidx.paging.map
import com.aiosman.ravenow.data.MomentService
import com.aiosman.ravenow.data.UserServiceImpl
import com.aiosman.ravenow.entity.AccountPagingSource
import com.aiosman.ravenow.entity.AccountProfileEntity
import com.aiosman.ravenow.entity.MomentEntity
import com.aiosman.ravenow.entity.MomentPagingSource
import com.aiosman.ravenow.entity.MomentRemoteDataSource
import com.aiosman.ravenow.entity.MomentServiceImpl
import com.aiosman.ravenow.event.MomentFavouriteChangeEvent
import com.aiosman.ravenow.event.MomentLikeChangeEvent
import com.aiosman.ravenow.entity.AgentEntity
import com.aiosman.ravenow.entity.AgentRemoteDataSource
import com.aiosman.ravenow.entity.AgentSearchPagingSource
import com.aiosman.ravenow.entity.AgentServiceImpl
import com.aiosman.ravenow.entity.RoomEntity
import com.aiosman.ravenow.entity.RoomRemoteDataSource
import com.aiosman.ravenow.entity.RoomSearchPagingSource
import com.aiosman.ravenow.utils.SearchHistoryStore
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus

object SearchViewModel : ViewModel() {
    var searchText by mutableStateOf("")
    private val momentService: MomentService = MomentServiceImpl()
    private val _momentsFlow = MutableStateFlow<PagingData<MomentEntity>>(PagingData.empty())
    val momentsFlow = _momentsFlow.asStateFlow()

    private val userService = UserServiceImpl()
    private val _usersFlow = MutableStateFlow<PagingData<AccountProfileEntity>>(PagingData.empty())
    val usersFlow = _usersFlow.asStateFlow()
    private val _agentsFlow = MutableStateFlow<PagingData<AgentEntity>>(PagingData.empty())
    val agentsFlow = _agentsFlow.asStateFlow()
    private val _roomsFlow = MutableStateFlow<PagingData<RoomEntity>>(PagingData.empty())
    val roomsFlow = _roomsFlow.asStateFlow()
    private lateinit var historyStore: SearchHistoryStore
    private val _historyFlow = MutableStateFlow<List<String>>(emptyList())
    val historyFlow = _historyFlow.asStateFlow()
    var showResult by mutableStateOf(false)
    var requestFocus by mutableStateOf(false)

    fun ensureInit(context: Context) {
        if (!::historyStore.isInitialized) {
            historyStore = SearchHistoryStore(context.applicationContext)
            _historyFlow.value = historyStore.getHistory()
        }
    }

    fun onTextChanged(newText: String) {
        searchText = newText
        if (newText.isBlank()) {
            showResult = false
        }
    }

    fun search() {
        if (searchText.isEmpty()) {
            return
        }
        // 记录历史
        if (::historyStore.isInitialized) {
            historyStore.add(searchText)
            _historyFlow.value = historyStore.getHistory()
        }
        viewModelScope.launch {
            Pager(
                config = PagingConfig(pageSize = 5, enablePlaceholders = false),
                pagingSourceFactory = {
                    MomentPagingSource(
                        MomentRemoteDataSource(momentService),
                        contentSearch = searchText
                    )
                }
            ).flow.cachedIn(viewModelScope).collectLatest {
                _momentsFlow.value = it
            }
        }
        viewModelScope.launch {
            Pager(
                config = PagingConfig(pageSize = 5, enablePlaceholders = false),
                pagingSourceFactory = {
                    AccountPagingSource(
                        userService,
                        nickname = searchText
                    )
                }
            ).flow.cachedIn(viewModelScope).collectLatest {
                _usersFlow.value = it
            }
        }
        viewModelScope.launch {
            Pager(
                config = PagingConfig(pageSize = 5, enablePlaceholders = false),
                pagingSourceFactory = {
                    AgentSearchPagingSource(
                        AgentRemoteDataSource(AgentServiceImpl()),
                        keyword = searchText
                    )
                }
            ).flow.cachedIn(viewModelScope).collectLatest {
                _agentsFlow.value = it
            }
        }
        viewModelScope.launch {
            Pager(
                config = PagingConfig(pageSize = 5, enablePlaceholders = false),
                pagingSourceFactory = {
                    RoomSearchPagingSource(
                        RoomRemoteDataSource(),
                        keyword = searchText
                    )
                }
            ).flow.cachedIn(viewModelScope).collectLatest {
                _roomsFlow.value = it
            }
        }
        showResult = true
    }

    fun removeHistoryItem(term: String) {
        if (!::historyStore.isInitialized) return
        historyStore.remove(term)
        _historyFlow.value = historyStore.getHistory()
    }

    fun clearHistory() {
        if (!::historyStore.isInitialized) return
        historyStore.clear()
        _historyFlow.value = emptyList()
    }

    suspend fun followUser(id:Int){
        userService.followUser(id.toString())
        val currentPagingData = _usersFlow.value
        val updatedPagingData = currentPagingData.map { userItem ->
            if (userItem.id == id) {
                userItem.copy(isFollowing = true, followerCount = userItem.followerCount + 1)
            } else {
                userItem
            }
        }
       _usersFlow.value = updatedPagingData
    }

    suspend fun unfollowUser(id:Int){
        userService.unFollowUser(id.toString())
        val currentPagingData = _usersFlow.value
        val updatedPagingData = currentPagingData.map { userItem ->
            if (userItem.id == id) {
                userItem.copy(isFollowing = false, followerCount = userItem.followerCount - 1)
            } else {
                userItem
            }
        }
       _usersFlow.value = updatedPagingData
    }

    fun ResetModel(){
        _momentsFlow.value = PagingData.empty()
        _usersFlow.value = PagingData.empty()
        _agentsFlow.value = PagingData.empty()
        _roomsFlow.value = PagingData.empty()
        showResult = false
    }

    fun updateMomentFollowStatus(authorId:Int,isFollow:Boolean) {
        val currentPagingData = _momentsFlow.value
        val updatedPagingData = currentPagingData.map { momentItem ->
            if (momentItem.authorId == authorId) {
                momentItem.copy(followStatus = isFollow)
            } else {
                momentItem
            }
        }
        _momentsFlow.value = updatedPagingData
    }
    fun momentFollowAction(moment: MomentEntity) {
        viewModelScope.launch {
            try {
                if (moment.followStatus) {
                    userService.unFollowUser(moment.authorId.toString())
                } else {
                    userService.followUser(moment.authorId.toString())
                }
                updateMomentFollowStatus(moment.authorId, !moment.followStatus)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

    suspend fun likeMoment(id: Int) {
        try {
            momentService.likeMoment(id)
            val likeCount = updateMomentLike(id, true)
            EventBus.getDefault().post(
                MomentLikeChangeEvent(
                    postId = id,
                    likeCount = likeCount,
                    isLike = true
                )
            )
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    suspend fun dislikeMoment(id: Int) {
        try {
            momentService.dislikeMoment(id)
            val likeCount = updateMomentLike(id, false)
            EventBus.getDefault().post(
                MomentLikeChangeEvent(
                    postId = id,
                    likeCount = likeCount,
                    isLike = false
                )
            )
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    suspend fun favoriteMoment(id: Int) {
        try {
            momentService.favoriteMoment(id)
            updateMomentFavorite(id, true)
            EventBus.getDefault().post(
                MomentFavouriteChangeEvent(
                    postId = id,
                    isFavourite = true
                )
            )
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    suspend fun unfavoriteMoment(id: Int) {
        try {
            momentService.unfavoriteMoment(id)
            updateMomentFavorite(id, false)
            EventBus.getDefault().post(
                MomentFavouriteChangeEvent(
                    postId = id,
                    isFavourite = false
                )
            )
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun onAddComment(id: Int) {
        updateMomentCommentCount(id, 1)
    }

    private fun updateMomentLike(id: Int, isLike: Boolean): Int? {
        var latestLikeCount: Int? = null
        val currentPagingData = _momentsFlow.value
        val updatedPagingData = currentPagingData.map { momentItem ->
            if (momentItem.id == id) {
                val nextCount = (momentItem.likeCount + if (isLike) 1 else -1).coerceAtLeast(0)
                latestLikeCount = nextCount
                momentItem.copy(
                    liked = isLike,
                    likeCount = nextCount
                )
            } else {
                momentItem
            }
        }
        _momentsFlow.value = updatedPagingData
        return latestLikeCount
    }

    private fun updateMomentFavorite(id: Int, isFavorite: Boolean) {
        val currentPagingData = _momentsFlow.value
        val updatedPagingData = currentPagingData.map { momentItem ->
            if (momentItem.id == id) {
                momentItem.copy(
                    isFavorite = isFavorite,
                    favoriteCount = (momentItem.favoriteCount + if (isFavorite) 1 else -1).coerceAtLeast(0)
                )
            } else {
                momentItem
            }
        }
        _momentsFlow.value = updatedPagingData
    }

    private fun updateMomentCommentCount(id: Int, delta: Int) {
        val currentPagingData = _momentsFlow.value
        val updatedPagingData = currentPagingData.map { momentItem ->
            if (momentItem.id == id) {
                momentItem.copy(
                    commentCount = (momentItem.commentCount + delta).coerceAtLeast(0)
                )
            } else {
                momentItem
            }
        }
        _momentsFlow.value = updatedPagingData
    }
}