package com.tt.honeyDue.viewmodel

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.tt.honeyDue.data.DataManager
import com.tt.honeyDue.data.IDataManager
import com.tt.honeyDue.models.*
import com.tt.honeyDue.network.APILayer
import com.tt.honeyDue.network.ApiResult
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch

/**
 * LookupsViewModel — already the template for reactive DataManager
 * derivation. Extended to accept [IDataManager] as a constructor param
 * so test doubles can be injected identically to every other VM.
 *
 * Direct StateFlow exposure (no wrapping) for the happy path:
 * screens observing [residenceTypes] etc. see the live [IDataManager]
 * value instantly.
 *
 * Legacy `*State: StateFlow<ApiResult<T>>` fields are kept for screens
 * still coded against the `ApiResult` pattern — they're now derived
 * from DataManager via `.map + .stateIn` so they emit `Success` as
 * soon as data is present, bypassing the old `_xxxState.value =`
 * write pattern.
 */
class LookupsViewModel(
    private val dataManager: IDataManager = DataManager,
) : ViewModel() {

    // ---------- Direct exposure (preferred) ----------

    val residenceTypes: StateFlow<List<ResidenceType>> = dataManager.residenceTypes
    val taskFrequencies: StateFlow<List<TaskFrequency>> = dataManager.taskFrequencies
    val taskPriorities: StateFlow<List<TaskPriority>> = dataManager.taskPriorities
    val taskCategories: StateFlow<List<TaskCategory>> = dataManager.taskCategories
    val contractorSpecialties: StateFlow<List<ContractorSpecialty>> = dataManager.contractorSpecialties

    // ---------- ApiResult-wrapped projections (legacy — derived) ----------

    val residenceTypesState: StateFlow<ApiResult<List<ResidenceType>>> =
        dataManager.residenceTypes
            .map { if (it.isNotEmpty()) ApiResult.Success(it) else ApiResult.Idle }
            .stateIn(viewModelScope, SharingStarted.Eagerly, ApiResult.Idle)

    val taskFrequenciesState: StateFlow<ApiResult<List<TaskFrequency>>> =
        dataManager.taskFrequencies
            .map { if (it.isNotEmpty()) ApiResult.Success(it) else ApiResult.Idle }
            .stateIn(viewModelScope, SharingStarted.Eagerly, ApiResult.Idle)

    val taskPrioritiesState: StateFlow<ApiResult<List<TaskPriority>>> =
        dataManager.taskPriorities
            .map { if (it.isNotEmpty()) ApiResult.Success(it) else ApiResult.Idle }
            .stateIn(viewModelScope, SharingStarted.Eagerly, ApiResult.Idle)

    val taskCategoriesState: StateFlow<ApiResult<List<TaskCategory>>> =
        dataManager.taskCategories
            .map { if (it.isNotEmpty()) ApiResult.Success(it) else ApiResult.Idle }
            .stateIn(viewModelScope, SharingStarted.Eagerly, ApiResult.Idle)

    // ---------- Load methods (write-through) ----------

    fun loadResidenceTypes() {
        if (dataManager.residenceTypes.value.isNotEmpty()) return
        viewModelScope.launch { APILayer.getResidenceTypes() }
    }

    fun loadTaskFrequencies() {
        if (dataManager.taskFrequencies.value.isNotEmpty()) return
        viewModelScope.launch { APILayer.getTaskFrequencies() }
    }

    fun loadTaskPriorities() {
        if (dataManager.taskPriorities.value.isNotEmpty()) return
        viewModelScope.launch { APILayer.getTaskPriorities() }
    }

    fun loadTaskCategories() {
        if (dataManager.taskCategories.value.isNotEmpty()) return
        viewModelScope.launch { APILayer.getTaskCategories() }
    }

    fun loadAllLookups() {
        loadResidenceTypes()
        loadTaskFrequencies()
        loadTaskPriorities()
        loadTaskCategories()
    }
}
