package de.tsschulz.tt_tagebuch.shared.state

import de.tsschulz.tt_tagebuch.shared.api.PermissionsApi
import de.tsschulz.tt_tagebuch.shared.api.models.AvailableRoleDto
import de.tsschulz.tt_tagebuch.shared.api.models.ClubPermissionMemberDto
import de.tsschulz.tt_tagebuch.shared.api.models.PermissionResourceDto
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update

data class PermissionsAdminState(
    val members: List<ClubPermissionMemberDto> = emptyList(),
    val availableRoles: List<AvailableRoleDto> = emptyList(),
    val permissionStructure: Map<String, PermissionResourceDto> = emptyMap(),
    val isLoading: Boolean = false,
    val error: String? = null,
)

class PermissionsAdminManager(
    private val permissionsApi: PermissionsApi,
) {
    private val _state = MutableStateFlow(PermissionsAdminState())
    val state: StateFlow<PermissionsAdminState> = _state.asStateFlow()

    fun clear() {
        _state.value = PermissionsAdminState()
    }

    suspend fun load(clubId: Int) {
        _state.update { it.copy(isLoading = true, error = null) }
        try {
            val roles = permissionsApi.listAvailableRoles()
            val structure = permissionsApi.getPermissionStructure()
            val members = permissionsApi.listClubMembersWithPermissions(clubId)
            _state.update {
                it.copy(
                    availableRoles = roles,
                    permissionStructure = structure,
                    members = members,
                    isLoading = false,
                    error = null,
                )
            }
        } catch (t: Throwable) {
            _state.update {
                it.copy(
                    isLoading = false,
                    error = t.toUserMessage("Berechtigungen konnten nicht geladen werden"),
                )
            }
        }
    }

    suspend fun reloadMembers(clubId: Int) {
        try {
            val members = permissionsApi.listClubMembersWithPermissions(clubId, cacheBust = true)
            _state.update { it.copy(members = members) }
        } catch (_: Throwable) { }
    }

    suspend fun updateRole(clubId: Int, userId: Int, role: String) {
        permissionsApi.updateUserRole(clubId, userId, role)
        load(clubId)
    }

    suspend fun updateApproved(clubId: Int, userId: Int, approved: Boolean) {
        permissionsApi.updateUserStatus(clubId, userId, approved)
        load(clubId)
    }

    suspend fun saveCustomPermissions(clubId: Int, userId: Int, permissions: kotlinx.serialization.json.JsonObject) {
        permissionsApi.updateUserCustomPermissions(clubId, userId, permissions)
        load(clubId)
    }
}
