package com.swoosh.microblog.data

import com.swoosh.microblog.data.model.FeedPost
import com.swoosh.microblog.data.model.QueueStatus
import org.junit.Assert.*
import org.junit.Test

class ShareUtilsTest {

    // --- getPostUrl tests ---

    @Test
    fun `getPostUrl constructs URL with base and slug`() {
        assertEquals(
            "https://blog.example.com/my-post/",
            ShareUtils.getPostUrl("https://blog.example.com", "my-post")
        )
    }

    @Test
    fun `getPostUrl handles base URL with trailing slash`() {
        assertEquals(
            "https://blog.example.com/my-post/",
            ShareUtils.getPostUrl("https://blog.example.com/", "my-post")
        )
    }

    @Test
    fun `getPostUrl handles base URL with multiple trailing slashes`() {
        assertEquals(
            "https://blog.example.com/my-post/",
            ShareUtils.getPostUrl("https://blog.example.com///", "my-post")
        )
    }

    @Test
    fun `getPostUrl handles slug with leading slash`() {
        assertEquals(
            "https://blog.example.com/my-post/",
            ShareUtils.getPostUrl("https://blog.example.com", "/my-post")
        )
    }

    @Test
    fun `getPostUrl handles slug with trailing slash`() {
        assertEquals(
            "https://blog.example.com/my-post/",
            ShareUtils.getPostUrl("https://blog.example.com", "my-post/")
        )
    }

    @Test
    fun `getPostUrl handles slug with both leading and trailing slashes`() {
        assertEquals(
            "https://blog.example.com/my-post/",
            ShareUtils.getPostUrl("https://blog.example.com", "/my-post/")
        )
    }

    @Test
    fun `getPostUrl handles subdomain base URL`() {
        assertEquals(
            "https://my-blog.ghost.io/hello-world/",
            ShareUtils.getPostUrl("https://my-blog.ghost.io", "hello-world")
        )
    }

    @Test
    fun `getPostUrl handles http base URL`() {
        assertEquals(
            "http://localhost:2368/test-post/",
            ShareUtils.getPostUrl("http://localhost:2368", "test-post")
        )
    }

    @Test
    fun `getPostUrl handles slug with hyphens`() {
        assertEquals(
            "https://blog.example.com/my-long-post-title-here/",
            ShareUtils.getPostUrl("https://blog.example.com", "my-long-post-title-here")
        )
    }

    // --- resolvePostUrl tests ---

    @Test
    fun `resolvePostUrl prefers url field when available`() {
        val post = createFeedPost(
            url = "https://blog.example.com/custom-url/",
            slug = "my-slug"
        )
        assertEquals(
            "https://blog.example.com/custom-url/",
            ShareUtils.resolvePostUrl(post, "https://blog.example.com")
        )
    }

    @Test
    fun `resolvePostUrl falls back to slug when url is null`() {
        val post = createFeedPost(slug = "my-slug", url = null)
        assertEquals(
            "https://blog.example.com/my-slug/",
            ShareUtils.resolvePostUrl(post, "https://blog.example.com")
        )
    }

    @Test
    fun `resolvePostUrl falls back to slug when url is blank`() {
        val post = createFeedPost(slug = "my-slug", url = "  ")
        assertEquals(
            "https://blog.example.com/my-slug/",
            ShareUtils.resolvePostUrl(post, "https://blog.example.com")
        )
    }

    @Test
    fun `resolvePostUrl returns null when no url and no slug`() {
        val post = createFeedPost(slug = null, url = null)
        assertNull(ShareUtils.resolvePostUrl(post, "https://blog.example.com"))
    }

    @Test
    fun `resolvePostUrl returns null when no url and blank slug`() {
        val post = createFeedPost(slug = "", url = null)
        assertNull(ShareUtils.resolvePostUrl(post, "https://blog.example.com"))
    }

    @Test
    fun `resolvePostUrl returns null when no url, has slug, but no base URL`() {
        val post = createFeedPost(slug = "my-slug", url = null)
        assertNull(ShareUtils.resolvePostUrl(post, null))
    }

    @Test
    fun `resolvePostUrl returns null when no url, has slug, but blank base URL`() {
        val post = createFeedPost(slug = "my-slug", url = null)
        assertNull(ShareUtils.resolvePostUrl(post, ""))
    }

    // --- formatShareContent tests ---

    @Test
    fun `formatShareContent includes text and read more link`() {
        val post = createFeedPost(textContent = "Hello world")
        val result = ShareUtils.formatShareContent(post, "https://blog.example.com/hello/")
        assertEquals(
            "Hello world\n\nRead more: https://blog.example.com/hello/",
            result
        )
    }

    @Test
    fun `formatShareContent truncates text over 280 chars`() {
        val longText = "a".repeat(300)
        val post = createFeedPost(textContent = longText)
        val result = ShareUtils.formatShareContent(post, "https://blog.example.com/post/")
        assertTrue(result.startsWith("a".repeat(280) + "..."))
        assertTrue(result.contains("Read more: https://blog.example.com/post/"))
    }

    @Test
    fun `formatShareContent does not truncate text at exactly 280 chars`() {
        val text = "b".repeat(280)
        val post = createFeedPost(textContent = text)
        val result = ShareUtils.formatShareContent(post, "https://blog.example.com/post/")
        assertTrue(result.startsWith(text))
        assertFalse(result.contains("..."))
    }

    @Test
    fun `formatShareContent includes link URL when present`() {
        val post = createFeedPost(
            textContent = "Check this out",
            linkUrl = "https://external.com/article"
        )
        val result = ShareUtils.formatShareContent(post, "https://blog.example.com/post/")
        assertEquals(
            "Check this out\n\nhttps://external.com/article\n\nRead more: https://blog.example.com/post/",
            result
        )
    }

    @Test
    fun `formatShareContent does not include link URL when null`() {
        val post = createFeedPost(textContent = "Hello", linkUrl = null)
        val result = ShareUtils.formatShareContent(post, "https://blog.example.com/post/")
        assertFalse(result.contains("https://external"))
        assertEquals("Hello\n\nRead more: https://blog.example.com/post/", result)
    }

    @Test
    fun `formatShareContent does not include link URL when blank`() {
        val post = createFeedPost(textContent = "Hello", linkUrl = "  ")
        val result = ShareUtils.formatShareContent(post, "https://blog.example.com/post/")
        assertEquals("Hello\n\nRead more: https://blog.example.com/post/", result)
    }

    @Test
    fun `formatShareContent handles empty text content`() {
        val post = createFeedPost(textContent = "")
        val result = ShareUtils.formatShareContent(post, "https://blog.example.com/post/")
        assertEquals("Read more: https://blog.example.com/post/", result)
    }

    @Test
    fun `formatShareContent handles whitespace-only text content`() {
        val post = createFeedPost(textContent = "   ")
        val result = ShareUtils.formatShareContent(post, "https://blog.example.com/post/")
        assertEquals("Read more: https://blog.example.com/post/", result)
    }

    @Test
    fun `formatShareContent handles empty text with link URL`() {
        val post = createFeedPost(textContent = "", linkUrl = "https://external.com")
        val result = ShareUtils.formatShareContent(post, "https://blog.example.com/post/")
        assertEquals("https://external.com\n\nRead more: https://blog.example.com/post/", result)
    }

    // --- Share visibility tests ---

    @Test
    fun `published post with slug is shareable`() {
        val post = createFeedPost(status = "published", slug = "my-post")
        val url = ShareUtils.resolvePostUrl(post, "https://blog.example.com")
        assertNotNull(url)
    }

    @Test
    fun `draft post is not shareable via url resolution`() {
        // Drafts don't typically have a slug or url from Ghost
        val post = createFeedPost(status = "draft", slug = null, url = null)
        val url = ShareUtils.resolvePostUrl(post, "https://blog.example.com")
        assertNull(url)
    }

    @Test
    fun `published post with url field is shareable`() {
        val post = createFeedPost(
            status = "published",
            slug = null,
            url = "https://blog.example.com/my-post/"
        )
        val url = ShareUtils.resolvePostUrl(post, "https://blog.example.com")
        assertEquals("https://blog.example.com/my-post/", url)
    }

    // --- Helper ---

    private fun createFeedPost(
        textContent: String = "Test content",
        slug: String? = null,
        url: String? = null,
        status: String = "published",
        linkUrl: String? = null,
        imageUrl: String? = null
    ) = FeedPost(
        localId = null,
        ghostId = "test-id",
        slug = slug,
        url = url,
        title = "",
        textContent = textContent,
        htmlContent = null,
        imageUrl = imageUrl,
        linkUrl = linkUrl,
        linkTitle = null,
        linkDescription = null,
        linkImageUrl = null,
        status = status,
        publishedAt = null,
        createdAt = null,
        updatedAt = null,
        isLocal = false,
        queueStatus = QueueStatus.NONE
    )
}
