package de.trainingstagebuch.app.network

import kotlinx.serialization.json.JsonElement
import de.trainingstagebuch.app.utils.SocketMessageUtils

sealed interface SocketConnectionState {
    data object Disconnected : SocketConnectionState
    data object Connecting : SocketConnectionState
    data class Connected(val attempts: Int) : SocketConnectionState
    data class Reconnecting(val attempts: Int, val delayMs: Long) : SocketConnectionState
    data class Failed(val reason: String?) : SocketConnectionState
}

data class SocketEvent(
    val type: SocketEventType,
    val rawType: String,
    val payload: JsonElement?
)

enum class SocketEventType(val wireName: String) {
    ParticipantAdded("participant:added"),
    ParticipantRemoved("participant:removed"),
    ParticipantUpdated("participant:updated"),
    DiaryNoteAdded("diary:note:added"),
    DiaryNoteUpdated("diary:note:updated"),
    DiaryNoteDeleted("diary:note:deleted"),
    DiaryTagAdded("diary:tag:added"),
    DiaryTagRemoved("diary:tag:removed"),
    DiaryDateUpdated("diary:date:updated"),
    ActivityMemberAdded("activity:member:added"),
    ActivityMemberRemoved("activity:member:removed"),
    ActivityChanged("activity:changed"),
    MemberChanged("member:changed"),
    GroupChanged("group:changed"),
    TournamentChanged("tournament:changed"),
    ScheduleMatchUpdated("schedule:match:updated"),
    ScheduleMatchReportSubmitted("schedule:match-report:submitted"),
    Unknown("unknown");

    companion object {
        fun fromWireName(name: String): SocketEventType {
            return when (name) {
                // backward compatibility: some backend builds may emit dash-variant
                "activity-member:added" -> ActivityMemberAdded
                "activity-member:removed" -> ActivityMemberRemoved
                else -> entries.firstOrNull { it.wireName == name } ?: Unknown
            }
        }
    }
}

object SocketEventParser {
    fun parseSocketIoEvent(rawMessage: String): SocketEvent? {
        return SocketMessageUtils.parseSocketIoEvent(rawMessage)
    }

    fun buildAuthMessage(authCode: String, userId: String): String {
        return SocketMessageUtils.buildAuthMessage(authCode, userId)
    }

    fun buildJoinClubMessage(clubId: String): String {
        return SocketMessageUtils.buildJoinClubMessage(clubId)
    }
}
