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

import com.runicgateway.app.data.api.AdminApi
import com.runicgateway.app.data.api.dto.AdminDashboardDto
import com.runicgateway.app.data.api.dto.AdminPostDto
import com.runicgateway.app.data.api.dto.AdminWikiCategoryDto
import com.runicgateway.app.data.api.dto.AdminWikiTagDto
import com.runicgateway.app.data.api.dto.BanRequest
import com.runicgateway.app.data.api.dto.BroadcastRequest
import com.runicgateway.app.data.api.dto.KickRequest
import com.runicgateway.app.data.api.dto.PageRespondRequest
import com.runicgateway.app.data.api.dto.PostCreateRequest
import com.runicgateway.app.data.api.dto.PublishRequest
import com.runicgateway.app.data.api.dto.SiteModeRequest
import com.runicgateway.app.data.api.dto.SiteModeStateDto
import com.runicgateway.app.data.api.dto.SupportPageDto
import com.runicgateway.app.data.api.dto.UnbanRequest
import com.runicgateway.app.data.api.dto.WikiCategoryRequest
import com.runicgateway.app.util.okUnit
import retrofit2.Response

/**
 * A configurable fake of [AdminApi] for the staff-ops repository/ViewModel tests.
 * Read endpoints return their `var`; write endpoints returning `Response<Unit>`
 * return [unitResponse] (default 200) so a test can drive the 200 / 403 / 503 copy
 * branches. Set [error] to throw from every call (network / decode failure paths).
 */
class FakeAdminApi : AdminApi {

    var error: Throwable? = null

    var dashboard: AdminDashboardDto = AdminDashboardDto()
    var siteMode: SiteModeStateDto = SiteModeStateDto()
    var posts: List<AdminPostDto> = emptyList()
    var createdPost: AdminPostDto = AdminPostDto(id = 0)
    var publishedPost: AdminPostDto = AdminPostDto(id = 0)
    var wikiCategories: List<AdminWikiCategoryDto> = emptyList()
    var createdCategory: AdminWikiCategoryDto = AdminWikiCategoryDto(id = 0)
    var wikiTags: List<AdminWikiTagDto> = emptyList()
    var supportPages: List<SupportPageDto> = emptyList()

    /** Response returned by the bodyless write endpoints (kick/ban/delete/respond/…). */
    var unitResponse: Response<Unit> = okUnit()

    /** Bodies seen by write calls, so a test can assert what was sent. */
    var lastPostCreate: PostCreateRequest? = null
    var lastBan: BanRequest? = null
    var lastRespond: Pair<String, PageRespondRequest>? = null

    private fun <T> reply(value: T): T {
        error?.let { throw it }
        return value
    }

    override suspend fun dashboard(): AdminDashboardDto = reply(dashboard)
    override suspend fun setSiteMode(body: SiteModeRequest): SiteModeStateDto = reply(siteMode)

    override suspend fun posts(): List<AdminPostDto> = reply(posts)
    override suspend fun createPost(body: PostCreateRequest): AdminPostDto {
        lastPostCreate = body
        return reply(createdPost)
    }
    override suspend fun publishPost(id: Long, body: PublishRequest): AdminPostDto = reply(publishedPost)
    override suspend fun deletePost(id: Long): Response<Unit> = reply(unitResponse)

    override suspend fun wikiCategories(): List<AdminWikiCategoryDto> = reply(wikiCategories)
    override suspend fun createWikiCategory(body: WikiCategoryRequest): AdminWikiCategoryDto = reply(createdCategory)
    override suspend fun deleteWikiCategory(id: Long): Response<Unit> = reply(unitResponse)
    override suspend fun wikiTags(): List<AdminWikiTagDto> = reply(wikiTags)

    override suspend fun kick(body: KickRequest): Response<Unit> = reply(unitResponse)
    override suspend fun ban(body: BanRequest): Response<Unit> {
        lastBan = body
        return reply(unitResponse)
    }
    override suspend fun unban(body: UnbanRequest): Response<Unit> = reply(unitResponse)
    override suspend fun broadcast(body: BroadcastRequest): Response<Unit> = reply(unitResponse)

    override suspend fun supportPages(): List<SupportPageDto> = reply(supportPages)
    override suspend fun respondPage(id: String, body: PageRespondRequest): Response<Unit> {
        lastRespond = id to body
        return reply(unitResponse)
    }
    override suspend fun closePage(id: String): Response<Unit> = reply(unitResponse)
}
