package com.pixelized.headache.ui.page.event.edit

import android.icu.util.Calendar
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import com.pixelized.headache.R
import com.pixelized.headache.repository.event.EventRepository
import com.pixelized.headache.ui.common.error.ErrorToast
import com.pixelized.headache.ui.common.error.ResourceErrorMessage
import com.pixelized.headache.utils.extention.event
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import javax.inject.Inject
import kotlin.math.max

@HiltViewModel
class EventEditBottomSheetViewModel @Inject constructor(
    private val repository: EventRepository,
    private val factory: EventEditFactory,
) : ViewModel() {

    private val _data = mutableStateOf<EventEditBottomSheetUio?>(null)
    val data: State<EventEditBottomSheetUio?> = _data

    private val _errors = MutableSharedFlow<ErrorToast>()
    val errors: SharedFlow<ErrorToast> = _errors

    fun show(
        eventId: Long? = null,
    ) {
        val event = eventId?.let { id -> repository.event(id = id) }
        _data.value = factory.convertToUio(event = event)
    }

    fun dismiss() {
        _data.value = null
    }

    fun onAddPill(pill: EventPillEditUio) {
        updatePill(
            pill = pill,
            delta = 1,
        )
    }

    fun onRemovePill(pill: EventPillEditUio) {
        updatePill(
            pill = pill,
            delta = -1,
        )
    }

    fun updatePill(pill: EventPillEditUio, delta: Int) {
        _data.value = _data.value?.let { data ->
            val index = data.pills.indexOfFirst {
                it.id == pill.id
            }
            val newPill = data.pills[index].copy(
                amount = max(data.pills[index].amount + delta, 0)
            )
            data.copy(
                pills = data.pills.toMutableList().also {
                    it[index] = newPill
                }
            )
        }
    }

    suspend fun delete() {
        val event = _data.value ?: return
        val eventId = event.id ?: return

        val success = repository.deleteEvent(eventId = eventId)

        if (success) {
            _data.value = null
        } else {
            val message = ResourceErrorMessage(message = R.string.error_edit_calendar)
            _errors.emit(message)
        }
    }

    suspend fun confirm() {
        val event = _data.value ?: return
        val date = Calendar.getInstance().apply { time = event.date }.event
        val description = factory.convertToDescription(pills = event.pills)

        val success = if (event.id == null) {
            repository.createEvent(
                title = "Céphalée",
                description = description,
                year = date.year,
                month = date.month,
                day = date.day,
            )
        } else {
            repository.updateEvent(
                id = event.id,
                title = "Céphalée",
                description = description,
                year = date.year,
                month = date.month,
                day = date.day,
            )
        }

        if (success) {
            repository.fetchEvents(
                startDate = Calendar.getInstance().apply {
                    time = event.date
                    add(Calendar.DAY_OF_MONTH, -1)
                }.event,
                endDate = Calendar.getInstance().apply {
                    time = event.date
                    add(Calendar.DAY_OF_MONTH, 1)
                }.event,
            )
            _data.value = null
        } else {
            val message = ResourceErrorMessage(message = R.string.error_edit_calendar)
            _errors.emit(message)
        }
    }
}