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

import com.runicgateway.app.core.result.ApiResult
import com.runicgateway.app.core.result.safeApiCall
import com.runicgateway.app.data.api.PlayerShardApi
import com.runicgateway.app.data.api.dto.CharProfileDto
import com.runicgateway.app.data.api.dto.CreateGameAccountRequest
import com.runicgateway.app.data.api.dto.PlayerHouseDto
import com.runicgateway.app.data.api.dto.RosterDto
import com.runicgateway.app.data.api.dto.ShardLinkDto
import com.runicgateway.app.data.api.dto.ShardLinkRequest
import com.runicgateway.app.data.api.dto.ShardLinkResultDto
import com.runicgateway.app.data.api.dto.VendorSaleDto
import com.runicgateway.app.data.api.dto.VendorSnapshotDto
import javax.inject.Inject
import javax.inject.Singleton

/**
 * A player's own game data + game-account linking (PLAN.md §6.3), over the
 * bearer-gated `/player/shard/…` surface. Every read returns a typed [ApiResult]
 * so a down shard (`503`) renders as "offline, retry" and a not-linked account
 * (`403`) is handled cleanly — the repository never throws for an expected
 * failure (§7). Ownership is enforced server-side.
 */
@Singleton
class PlayerShardRepository @Inject constructor(
    private val api: PlayerShardApi,
) {
    suspend fun link(code: String): ApiResult<ShardLinkResultDto> =
        safeApiCall { api.link(ShardLinkRequest(code)) }

    suspend fun createAccount(account: String, password: String): ApiResult<ShardLinkResultDto> =
        safeApiCall { api.createAccount(CreateGameAccountRequest(account, password)) }

    suspend fun accounts(): ApiResult<List<ShardLinkDto>> = safeApiCall { api.accounts() }

    suspend fun roster(account: String): ApiResult<RosterDto> = safeApiCall { api.roster(account) }

    suspend fun char(serial: String): ApiResult<CharProfileDto> = safeApiCall { api.char(serial) }

    suspend fun vendors(account: String): ApiResult<VendorSnapshotDto> =
        safeApiCall { api.vendors(account) }

    suspend fun sales(): ApiResult<List<VendorSaleDto>> = safeApiCall { api.sales() }

    suspend fun houses(): ApiResult<List<PlayerHouseDto>> = safeApiCall { api.houses() }
}
