package com.atridad.ascently.data.model

import androidx.compose.runtime.Immutable
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Index
import androidx.room.PrimaryKey
import com.atridad.ascently.utils.DateFormatUtils
import kotlinx.serialization.Serializable

@Serializable
enum class SessionStatus {
    ACTIVE,
    COMPLETED,
    PAUSED,
}

@Entity(
    tableName = "climb_sessions",
    foreignKeys =
    [
        ForeignKey(
            entity = Gym::class,
            parentColumns = ["id"],
            childColumns = ["gymId"],
            onDelete = ForeignKey.CASCADE,
        ),
    ],
    indices = [Index(value = ["gymId"])],
)
@Immutable
@Serializable
data class ClimbSession(
    @PrimaryKey val id: String,
    val gymId: String,
    val date: String,
    val startTime: String? = null,
    val endTime: String? = null,
    val duration: Long? = null,
    val status: SessionStatus = SessionStatus.ACTIVE,
    val notes: String? = null,
    val createdAt: String,
    val updatedAt: String,
) {
    companion object {
        fun create(gymId: String, notes: String? = null): ClimbSession {
            val now = DateFormatUtils.nowISO8601()
            return ClimbSession(
                id = java.util.UUID.randomUUID().toString(),
                gymId = gymId,
                date = now,
                startTime = now,
                status = SessionStatus.ACTIVE,
                notes = notes,
                createdAt = now,
                updatedAt = now,
            )
        }

        fun ClimbSession.complete(): ClimbSession {
            val endTime = DateFormatUtils.nowISO8601()
            val durationMinutes =
                if (startTime != null) {
                    try {
                        val start = DateFormatUtils.parseISO8601(startTime)
                        val end = DateFormatUtils.parseISO8601(endTime)
                        if (start != null && end != null) {
                            java.time.Duration.between(start, end).toMinutes()
                        } else {
                            null
                        }
                    } catch (_: Exception) {
                        null
                    }
                } else {
                    null
                }

            return this.copy(
                endTime = endTime,
                duration = durationMinutes,
                status = SessionStatus.COMPLETED,
                updatedAt = DateFormatUtils.nowISO8601(),
            )
        }
    }
}
