package com.swoosh.microblog.data.model

import org.junit.Assert.*
import org.junit.Test

class OverallStatsTest {

    @Test
    fun `calculate with empty lists returns zero stats`() {
        val stats = OverallStats.calculate(emptyList(), emptyList())
        assertEquals(0, stats.totalPosts)
        assertEquals(0, stats.publishedCount)
        assertEquals(0, stats.draftCount)
        assertEquals(0, stats.scheduledCount)
        assertEquals(0, stats.totalWords)
        assertEquals(0, stats.totalCharacters)
        assertEquals(0, stats.averageWordCount)
        assertEquals(0, stats.averageCharCount)
        assertEquals(0, stats.longestPostWords)
        assertEquals(0, stats.shortestPostWords)
    }

    @Test
    fun `calculate counts local posts by status`() {
        val localPosts = listOf(
            LocalPost(localId = 1, content = "hello", status = PostStatus.DRAFT),
            LocalPost(localId = 2, content = "world", status = PostStatus.PUBLISHED),
            LocalPost(localId = 3, content = "foo bar", status = PostStatus.SCHEDULED)
        )
        val stats = OverallStats.calculate(localPosts, emptyList())
        assertEquals(3, stats.totalPosts)
        assertEquals(1, stats.publishedCount)
        assertEquals(1, stats.draftCount)
        assertEquals(1, stats.scheduledCount)
    }

    @Test
    fun `calculate counts remote posts by status`() {
        val remotePosts = listOf(
            makeFeedPost("hello world", "published"),
            makeFeedPost("foo bar", "published"),
            makeFeedPost("baz", "draft")
        )
        val stats = OverallStats.calculate(emptyList(), remotePosts)
        assertEquals(3, stats.totalPosts)
        assertEquals(2, stats.publishedCount)
        assertEquals(1, stats.draftCount)
        assertEquals(0, stats.scheduledCount)
    }

    @Test
    fun `calculate computes total words`() {
        val localPosts = listOf(
            LocalPost(localId = 1, content = "hello world"), // 2 words
            LocalPost(localId = 2, content = "foo bar baz")  // 3 words
        )
        val stats = OverallStats.calculate(localPosts, emptyList())
        assertEquals(5, stats.totalWords)
    }

    @Test
    fun `calculate computes total characters`() {
        val localPosts = listOf(
            LocalPost(localId = 1, content = "hello"), // 5 chars
            LocalPost(localId = 2, content = "world")  // 5 chars
        )
        val stats = OverallStats.calculate(localPosts, emptyList())
        assertEquals(10, stats.totalCharacters)
    }

    @Test
    fun `calculate computes average word count`() {
        val localPosts = listOf(
            LocalPost(localId = 1, content = "hello world"),          // 2 words
            LocalPost(localId = 2, content = "one two three four")    // 4 words
        )
        val stats = OverallStats.calculate(localPosts, emptyList())
        assertEquals(3, stats.averageWordCount) // (2 + 4) / 2 = 3
    }

    @Test
    fun `calculate computes average char count`() {
        val localPosts = listOf(
            LocalPost(localId = 1, content = "hello"),     // 5 chars
            LocalPost(localId = 2, content = "world!!")    // 7 chars
        )
        val stats = OverallStats.calculate(localPosts, emptyList())
        assertEquals(6, stats.averageCharCount) // (5 + 7) / 2 = 6
    }

    @Test
    fun `calculate finds longest post`() {
        val localPosts = listOf(
            LocalPost(localId = 1, content = "hello"),                       // 1 word
            LocalPost(localId = 2, content = "one two three four five six")  // 6 words
        )
        val stats = OverallStats.calculate(localPosts, emptyList())
        assertEquals(6, stats.longestPostWords)
    }

    @Test
    fun `calculate finds shortest post`() {
        val localPosts = listOf(
            LocalPost(localId = 1, content = "hello"),                       // 1 word
            LocalPost(localId = 2, content = "one two three four five six")  // 6 words
        )
        val stats = OverallStats.calculate(localPosts, emptyList())
        assertEquals(1, stats.shortestPostWords)
    }

    @Test
    fun `calculate combines local and remote posts`() {
        val localPosts = listOf(
            LocalPost(localId = 1, content = "local post", status = PostStatus.DRAFT)
        )
        val remotePosts = listOf(
            makeFeedPost("remote post here", "published")
        )
        val stats = OverallStats.calculate(localPosts, remotePosts)
        assertEquals(2, stats.totalPosts)
        assertEquals(1, stats.publishedCount)
        assertEquals(1, stats.draftCount)
        assertEquals(5, stats.totalWords) // 2 + 3
    }

    @Test
    fun `calculate handles scheduled remote posts`() {
        val remotePosts = listOf(
            makeFeedPost("scheduled post", "scheduled")
        )
        val stats = OverallStats.calculate(emptyList(), remotePosts)
        assertEquals(1, stats.scheduledCount)
    }

    @Test
    fun `calculate handles single post`() {
        val localPosts = listOf(
            LocalPost(localId = 1, content = "single word test post")
        )
        val stats = OverallStats.calculate(localPosts, emptyList())
        assertEquals(1, stats.totalPosts)
        assertEquals(4, stats.averageWordCount) // same as total since only 1 post
        assertEquals(stats.longestPostWords, stats.shortestPostWords)
    }

    @Test
    fun `default OverallStats has zero values`() {
        val stats = OverallStats()
        assertEquals(0, stats.totalPosts)
        assertEquals(0, stats.totalWords)
    }

    private fun makeFeedPost(text: String, status: String): FeedPost {
        return FeedPost(
            title = "",
            textContent = text,
            htmlContent = null,
            imageUrl = null,
            linkUrl = null,
            linkTitle = null,
            linkDescription = null,
            linkImageUrl = null,
            status = status,
            publishedAt = null,
            createdAt = null,
            updatedAt = null
        )
    }
}
