/*
 * SPDX-License-Identifier: GPL-3.0-or-later
 */
package com.runicgateway.app.ui.admin

import androidx.annotation.StringRes
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.runicgateway.app.R
import com.runicgateway.app.core.result.ApiResult
import com.runicgateway.app.data.api.dto.AdminDashboardDto
import com.runicgateway.app.data.repository.AdminRepository
import com.runicgateway.app.ui.UiState
import com.runicgateway.app.ui.toUiState
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.inject.Inject

/**
 * Drives the staff dashboard (PLAN.md §1, M10): summary counts + the site-mode
 * toggle. The mode switch is admin-only server-side (`adminOnly`); the screen only
 * offers it to admins, but a `403` is still handled cleanly if a moderator reaches
 * it. Everything is read through the typed [AdminRepository] (§7).
 */
@HiltViewModel
class AdminDashboardViewModel @Inject constructor(
    private val admin: AdminRepository,
) : ViewModel() {

    data class Feedback(val ok: Boolean, @param:StringRes val messageRes: Int)

    data class State(
        val dashboard: UiState<AdminDashboardDto> = UiState.Loading,
        /** True while a site-mode switch is in flight (disables the control). */
        val switching: Boolean = false,
        val feedback: Feedback? = null,
    )

    private val _state = MutableStateFlow(State())
    val state: StateFlow<State> = _state.asStateFlow()

    init {
        load()
    }

    fun load() {
        _state.update { it.copy(dashboard = UiState.Loading) }
        viewModelScope.launch {
            _state.update { it.copy(dashboard = admin.dashboard().toUiState()) }
        }
    }

    fun clearFeedback() = _state.update { it.copy(feedback = null) }

    /** Switch the site between "live" and "maintenance" (admin only). */
    fun setSiteMode(mode: String) {
        if (_state.value.switching) return
        _state.update { it.copy(switching = true, feedback = null) }
        viewModelScope.launch {
            when (val result = admin.setSiteMode(mode)) {
                is ApiResult.Ok -> {
                    // Reflect the new mode locally, then refresh the full summary.
                    val current = _state.value.dashboard
                    if (current is UiState.Success) {
                        _state.update {
                            it.copy(dashboard = UiState.Success(current.data.copy(siteMode = result.data.siteMode)))
                        }
                    }
                    _state.update { it.copy(switching = false, feedback = Feedback(true, R.string.admin_site_mode_updated)) }
                    load()
                }
                is ApiResult.HttpError ->
                    _state.update {
                        it.copy(
                            switching = false,
                            feedback = Feedback(
                                false,
                                if (result.status == 403) R.string.admin_forbidden else R.string.admin_action_failed,
                            ),
                        )
                    }
                is ApiResult.NetworkError ->
                    _state.update { it.copy(switching = false, feedback = Feedback(false, R.string.error_network)) }
            }
        }
    }
}
