package com.ponzischeme89.memby.ui

import android.graphics.BitmapFactory
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.onRoot
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.test.core.app.ApplicationProvider
import androidx.tv.material3.Text
import com.github.takahirom.roborazzi.captureRoboImage
import com.ponzischeme89.memby.ServiceLocator
import com.ponzischeme89.memby.data.model.BaseItem
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.robolectric.annotation.GraphicsMode

@RunWith(RobolectricTestRunner::class)
@GraphicsMode(GraphicsMode.Mode.NATIVE)
@Config(sdk = [34], qualifiers = "w960dp-h540dp-television-xhdpi")
class HomeMovieHeroScreenshotTest {
    @get:Rule
    val compose = createComposeRule()

    @Before
    fun locator() {
        ServiceLocator.init(ApplicationProvider.getApplicationContext())
    }

    @Test
    fun `home hero with popular and new releases`() {
        capture("df_home-movie-hero", movies)
    }

    /**
     * The case the audit reproduced: with a title long enough to wrap, the card's content
     * column overflowed its fixed height and the green Play chip — the last thing in the
     * column — was clipped away entirely. It has to survive here.
     */
    @Test
    fun `home hero with a wrapping title`() {
        capture(
            "df_home-movie-hero-long-title",
            listOf(
                HomeHeroPick(
                    movie(
                        "The Longest Northbound Winter",
                        2026,
                        "A cartographer chasing a river that no longer exists finds the last " +
                            "village on the map still waiting for him.",
                        8.4,
                    ),
                    "NEW RELEASE",
                ),
            ) + movies.drop(1),
        )
    }

    /**
     * The hero the gateway composes. Two things are only checkable by looking: the reason
     * takes the synopsis's place rather than adding a line above the Play chip, and a
     * series premiere leading the launcher has to read as deliberate rather than as a TV
     * show that wandered into the movie hero.
     */
    @Test
    fun `home hero composed by the gateway`() {
        capture(
            "df_home-movie-hero-server",
            listOf(
                HomeHeroPick(
                    series(
                        "The Quiet Coast",
                        2026,
                        "A harbour town's constable is the only one who noticed the tide change.",
                        8.6,
                    ),
                    "SERIES PREMIERE",
                    "A new series premiered yesterday",
                ),
                HomeHeroPick(
                    movie("Midnight Signal", 2026, "A city hears tomorrow's emergency broadcast.", 8.2),
                    "NEW RELEASE",
                    "Well reviewed, released on Monday",
                ),
                HomeHeroPick(
                    series("Harbour Lights", 2024, "The fourth season opens on an empty pier.", 8.1),
                    "NEW SEASON",
                    "A new season started today",
                ),
                HomeHeroPick(
                    movie("After the Fire", 2026, "Two strangers cross a country waking from winter.", 8.4),
                    "HIGHLY RATED",
                    "One of the best-reviewed titles in your library",
                ),
            ),
        )
    }

    /** The reason must not be what breaks the layout the wrapping-title case pins. */
    @Test
    fun `home hero with a wrapping title and a reason`() {
        capture(
            "df_home-movie-hero-long-title-reason",
            listOf(
                HomeHeroPick(
                    movie(
                        "The Longest Northbound Winter",
                        2026,
                        "A cartographer chasing a river that no longer exists finds the last " +
                            "village on the map still waiting for him.",
                        8.4,
                    ),
                    "NEW RELEASE",
                    "Well reviewed, released yesterday",
                ),
            ) + movies.drop(1),
        )
    }

    private fun capture(name: String, movies: List<HomeHeroPick>) {
        val artwork = requireNotNull(javaClass.getResourceAsStream("/home_hero_preview_art.png"))
            .use(BitmapFactory::decodeStream)
            .asImageBitmap()
        val railFocus = FocusRequester()

        compose.setContent {
            PreviewSurface(alignment = Alignment.TopStart) {
                Row(Modifier.fillMaxSize()) {
                    TvNavigationRail(
                        selected = BrowseDestination.HOME,
                        expanded = false,
                        navigationFocusRequester = railFocus,
                        onRailFocusChanged = {},
                        onDestinationSelected = {},
                    )
                    Column(Modifier.weight(1f).fillMaxHeight()) {
                        HomeMovieHero(
                            movies = movies,
                            navigationFocusRequester = railFocus,
                            onItemFocused = {},
                            onItemSelected = {},
                            modifier = Modifier.height(homeHeaderHeight(540.dp, showHero = true)),
                            previewArtwork = artwork,
                        )
                        Text(
                            "Recently added movies",
                            color = Color(0xFFF1F3F4),
                            fontSize = 18.sp,
                            modifier = Modifier.padding(start = 36.dp, top = 6.dp, bottom = 9.dp),
                        )
                        Row(
                            modifier = Modifier.fillMaxWidth().padding(horizontal = 36.dp),
                            horizontalArrangement = Arrangement.spacedBy(12.dp),
                        ) {
                            repeat(5) { index ->
                                Column(Modifier.weight(1f)) {
                                    Box(
                                        Modifier
                                            .fillMaxWidth()
                                            .aspectRatio(16f / 9f)
                                            .clip(RoundedCornerShape(7.dp))
                                            .background(
                                                listOf(
                                                    Color(0xFF27343D), Color(0xFF28302D),
                                                    Color(0xFF352C37), Color(0xFF392F28), Color(0xFF25343A),
                                                )[index],
                                            ),
                                    )
                                    Text(
                                        movies[index % movies.size].item.name,
                                        color = Color.White,
                                        fontSize = 13.sp,
                                        maxLines = 1,
                                        overflow = TextOverflow.Ellipsis,
                                        modifier = Modifier.padding(top = 6.dp),
                                    )
                                    Text(
                                        "2026  •  2h 4m",
                                        color = Color(0xFF8F9AA3),
                                        fontSize = 11.sp,
                                        modifier = Modifier.padding(top = 2.dp),
                                    )
                                }
                            }
                        }
                    }
                }
            }
        }

        compose.onNodeWithText("Play").fetchSemanticsNode()
        compose.onRoot().captureRoboImage("build/screenshots/home-movie-hero/$name.png")
    }

    private val movies = listOf(
        HomeHeroPick(
            movie(
                "The Last Horizon",
                2026,
                "Beyond the mapped worlds, one explorer finds an ocean that remembers every visitor.",
                8.7,
            ),
            "NEW RELEASE",
        ),
        HomeHeroPick(
            movie("Midnight Signal", 2026, "A city hears tomorrow's emergency broadcast.", 8.2),
            "POPULAR",
        ),
        HomeHeroPick(
            movie("Northstar Run", 2025, "The final supply ship takes an impossible route.", 7.9),
            "NEW RELEASE",
        ),
        HomeHeroPick(
            movie("After the Fire", 2026, "Two strangers cross a country waking from winter.", 8.4),
            "FROM YOUR LIBRARY",
        ),
    )

    private fun series(name: String, year: Int, overview: String, rating: Double) =
        movie(name, year, overview, rating).copy(type = "Series")

    private fun movie(name: String, year: Int, overview: String, rating: Double) = BaseItem(
        id = name.lowercase().replace(' ', '-'),
        name = name,
        type = "Movie",
        overview = overview,
        productionYear = year,
        officialRating = "M",
        communityRating = rating,
        runTimeTicks = 124L * 600_000_000L,
    )
}
