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

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.runicgateway.app.core.result.ApiResult
import com.runicgateway.app.core.result.map
import com.runicgateway.app.data.api.dto.VendorDto
import com.runicgateway.app.data.api.dto.VendorSaleDto
import com.runicgateway.app.data.repository.PlayerShardRepository
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

/**
 * The player's own player-vendors and recent vendor sales (PLAN.md §6.3): a
 * per-account vendor snapshot (shops + listings) over `/player/shard/vendors/:account`
 * plus the recent-sales log over `/player/shard/sales`. Each account's snapshot
 * carries its own load state so a down shard degrades one account to a retry (§7).
 * Text-only listings — item names are clilocs the app has no table for.
 */
@HiltViewModel
class VendorsViewModel @Inject constructor(
    private val repository: PlayerShardRepository,
) : ViewModel() {

    data class State(
        val accounts: UiState<List<String>> = UiState.Loading,
        val vendors: Map<String, UiState<List<VendorDto>>> = emptyMap(),
        val sales: UiState<List<VendorSaleDto>> = UiState.Loading,
    )

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

    init {
        load()
    }

    fun load() {
        _state.update { it.copy(accounts = UiState.Loading, vendors = emptyMap(), sales = UiState.Loading) }
        viewModelScope.launch {
            when (val result = repository.accounts()) {
                is ApiResult.Ok -> {
                    val names = result.data.map { it.account }
                    _state.update { it.copy(accounts = UiState.Success(names)) }
                    names.forEach { loadVendors(it) }
                }
                else -> _state.update { it.copy(accounts = result.map { emptyList<String>() }.toUiState()) }
            }
        }
        viewModelScope.launch {
            _state.update { it.copy(sales = repository.sales().toUiState()) }
        }
    }

    fun loadVendors(account: String) {
        _state.update { it.copy(vendors = it.vendors + (account to UiState.Loading)) }
        viewModelScope.launch {
            val vendors = repository.vendors(account).map { it.vendors }.toUiState()
            _state.update { it.copy(vendors = it.vendors + (account to vendors)) }
        }
    }
}
