package com.swoosh.microblog.ui.members

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import com.swoosh.microblog.data.model.GhostMember
import com.swoosh.microblog.data.repository.MemberRepository
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

enum class MemberFilter(val displayName: String, val ghostFilter: String?) {
    ALL("All", null),
    FREE("Free", "status:free"),
    PAID("Paid", "status:paid")
}

data class MembersUiState(
    val members: List<GhostMember> = emptyList(),
    val totalCount: Int = 0,
    val isLoading: Boolean = false,
    val isLoadingMore: Boolean = false,
    val hasMore: Boolean = false,
    val currentPage: Int = 1,
    val filter: MemberFilter = MemberFilter.ALL,
    val searchQuery: String = "",
    val error: String? = null
)

class MembersViewModel(application: Application) : AndroidViewModel(application) {

    private val repository = MemberRepository(application)

    private val _uiState = MutableStateFlow(MembersUiState())
    val uiState: StateFlow<MembersUiState> = _uiState.asStateFlow()

    private var searchJob: Job? = null

    init {
        loadMembers()
    }

    fun loadMembers() {
        viewModelScope.launch {
            _uiState.update { it.copy(isLoading = true, error = null, currentPage = 1) }

            val filter = buildFilter()
            val result = repository.fetchMembers(page = 1, limit = 15, filter = filter)

            result.fold(
                onSuccess = { response ->
                    _uiState.update {
                        it.copy(
                            members = response.members,
                            totalCount = response.meta?.pagination?.total ?: response.members.size,
                            hasMore = response.meta?.pagination?.next != null,
                            currentPage = 1,
                            isLoading = false
                        )
                    }
                },
                onFailure = { e ->
                    _uiState.update {
                        it.copy(isLoading = false, error = e.message)
                    }
                }
            )
        }
    }

    fun loadMore() {
        val state = _uiState.value
        if (state.isLoadingMore || !state.hasMore) return

        viewModelScope.launch {
            val nextPage = state.currentPage + 1
            _uiState.update { it.copy(isLoadingMore = true) }

            val filter = buildFilter()
            val result = repository.fetchMembers(page = nextPage, limit = 15, filter = filter)

            result.fold(
                onSuccess = { response ->
                    _uiState.update {
                        it.copy(
                            members = it.members + response.members,
                            hasMore = response.meta?.pagination?.next != null,
                            currentPage = nextPage,
                            isLoadingMore = false
                        )
                    }
                },
                onFailure = { e ->
                    _uiState.update {
                        it.copy(isLoadingMore = false, error = e.message)
                    }
                }
            )
        }
    }

    fun updateFilter(newFilter: MemberFilter) {
        if (newFilter == _uiState.value.filter) return
        _uiState.update { it.copy(filter = newFilter) }
        loadMembers()
    }

    fun search(query: String) {
        _uiState.update { it.copy(searchQuery = query) }
        searchJob?.cancel()
        searchJob = viewModelScope.launch {
            delay(300) // debounce
            loadMembers()
        }
    }

    private fun buildFilter(): String? {
        val parts = mutableListOf<String>()

        // Status filter
        _uiState.value.filter.ghostFilter?.let { parts.add(it) }

        // Search filter
        val query = _uiState.value.searchQuery.trim()
        if (query.isNotEmpty()) {
            parts.add("name:~'$query',email:~'$query'")
        }

        return parts.takeIf { it.isNotEmpty() }?.joinToString("+")
    }
}
