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

import com.runicgateway.app.R
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.fake.FakeAdminApi
import com.runicgateway.app.data.repository.AdminRepository
import com.runicgateway.app.ui.UiState
import com.runicgateway.app.util.MainDispatcherRule
import com.runicgateway.app.util.errorUnit
import com.runicgateway.app.util.httpError
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Rule
import org.junit.Test

class AdminContentViewModelTest {

    @get:Rule val mainDispatcher = MainDispatcherRule()

    private val api = FakeAdminApi()
    private fun viewModel() = AdminContentViewModel(AdminRepository(api))

    @Test fun loadsPostsAndWikiOnInit() {
        api.posts = listOf(AdminPostDto(id = 1, title = "A", published = 1))
        api.wikiCategories = listOf(AdminWikiCategoryDto(id = 2, slug = "lore", title = "Lore"))
        api.wikiTags = listOf(AdminWikiTagDto(id = 3, slug = "pvp", label = "PvP"))
        val vm = viewModel()
        assertTrue(vm.state.value.posts is UiState.Success)
        assertEquals(1, (vm.state.value.posts as UiState.Success).data.size)
        assertEquals(1, vm.state.value.tags.size)
    }

    @Test fun createPostRejectsBlankTitleWithoutCallingApi() {
        val vm = viewModel()
        vm.createPost(category = "news", title = "  ", excerpt = "", body = "", published = false)
        assertFalse(vm.state.value.feedback!!.ok)
        assertEquals(R.string.admin_content_title_required, vm.state.value.feedback!!.messageRes)
        assertEquals(null, api.lastPostCreate) // never reached the API
    }

    @Test fun createPostTrimsAndNullsBlanksThenReloads() {
        val vm = viewModel()
        vm.createPost(category = "news", title = "  Hello ", excerpt = "", body = "b", published = true)
        val sent = api.lastPostCreate!!
        assertEquals("Hello", sent.title)
        assertEquals(null, sent.excerpt) // blank -> null
        assertEquals("b", sent.body)
        assertTrue(vm.state.value.feedback!!.ok)
        assertFalse(vm.state.value.busy)
    }

    @Test fun togglePublishForbiddenSurfacesForbiddenCopy() {
        api.unitResponse = errorUnit(403)
        api.error = httpError(403)
        val vm = viewModel()
        vm.togglePublish(AdminPostDto(id = 5, title = "x", published = 1))
        assertEquals(R.string.admin_forbidden, vm.state.value.feedback!!.messageRes)
    }

    @Test fun createCategoryRejectsBlankFields() {
        val vm = viewModel()
        vm.createCategory(slug = "", title = "", description = "", sortOrder = null)
        assertEquals(R.string.admin_content_cat_fields_required, vm.state.value.feedback!!.messageRes)
    }

    @Test fun deletePostNetworkErrorShowsNetworkCopy() {
        api.error = java.io.IOException("offline")
        val vm = viewModel()
        vm.deletePost(9)
        assertEquals(R.string.error_network, vm.state.value.feedback!!.messageRes)
    }
}
