import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.material3.OutlinedCard
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.unit.dp
import domain.Clue
import domain.Grid
import domain.HorizontalClue
import domain.ItemClass
import domain.NeighbourClue
import domain.OrderClue
import domain.SameColumnClue
import domain.TripletClue
import domain.generateGame
import org.jetbrains.compose.resources.painterResource
import ui.DrawItem
import ui.Selector
import yaep.composeapp.generated.resources.Res
import yaep.composeapp.generated.resources.neighbour
import yaep.composeapp.generated.resources.order

class DisplayClue<C : Clue>(val clue: C) {
    var isActive by mutableStateOf(true)
}

@Composable
fun App(modifier: Modifier = Modifier) {
    val game = remember { generateGame() }
    val horizontalClues = remember { game.horizontalClues.map { DisplayClue(it) } }
    val verticalClues = remember { game.verticalClues.map { DisplayClue(it) } }
    Row(modifier = modifier) {
        PuzzleGrid(modifier = Modifier.weight(1f), game.grid)
        PuzzleClues(modifier = Modifier.weight(1f), horizontalClues, verticalClues)
    }
}

@Composable
fun PuzzleGrid(
    modifier: Modifier = Modifier,
    grid: Grid
) {
    Column(modifier = modifier) {
        for (row in grid.rows) {
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .wrapContentHeight()
            ) {
                for (item in row) {
                    Selector(
                        modifier = Modifier
                            .padding(4.dp)
                            .weight(1f),
                        category = row.category,
                        options = item.options,
                        selectedItem = item.selection,
                        onSelectItem = { item.selection = it }
                    )
                }
            }
        }
    }
}

@Composable
fun PuzzleClues(
    modifier: Modifier = Modifier,
    horizontalClues: List<DisplayClue<HorizontalClue>>,
    verticalClues: List<DisplayClue<SameColumnClue<ItemClass<*>, ItemClass<*>>>>
) {
    Column(modifier = modifier) {
        LazyVerticalGrid(
            modifier = Modifier.fillMaxWidth().weight(1f),
            columns = GridCells.Adaptive(32.dp)
        ) {
            for (clue in horizontalClues.filter { it.isActive }) {
                item {
                    HorizontalClue(
                        modifier = Modifier.clickable { clue.isActive = false },
                        clue = clue.clue
                    )
                }
            }
            for (clue in horizontalClues.filter { !it.isActive }) {
                item {
                    HorizontalClue(
                        modifier = Modifier
                            .alpha(0.5f)
                            .clickable { clue.isActive = true },
                        clue = clue.clue
                    )
                }
            }
        }

        LazyVerticalGrid(
            modifier = Modifier.fillMaxWidth().weight(1f),
            columns = GridCells.Adaptive(32.dp)
        ) {
            for (clue in verticalClues.filter { it.isActive }) {
                item {
                    VerticalClue(
                        modifier = Modifier.clickable { clue.isActive = false },
                        clue = clue.clue
                    )
                }
            }
            for (clue in verticalClues.filter { !it.isActive }) {
                item {
                    VerticalClue(
                        modifier = Modifier
                            .alpha(0.5f)
                            .clickable { clue.isActive = true },
                        clue = clue.clue
                    )
                }
            }
        }
    }
}

@Composable
fun HorizontalClue(modifier: Modifier = Modifier, clue: HorizontalClue) {
    Column {
        when (clue) {
            is NeighbourClue<*, *> -> {
                DrawItem(modifier = Modifier.weight(1f), clue.a)
                OutlinedCard(modifier = modifier.aspectRatio(1f).weight(1f)) {
                    Image(
                        painter = painterResource(Res.drawable.neighbour),
                        contentDescription = null
                    )
                }
                DrawItem(modifier = Modifier.weight(1f), clue.b)
            }

            is OrderClue<*, *> -> {
                DrawItem(modifier = Modifier.weight(1f), clue.left)
                OutlinedCard(modifier = modifier.aspectRatio(1f).weight(1f)) {
                    Image(painter = painterResource(Res.drawable.order), contentDescription = null)
                }
                DrawItem(modifier = Modifier.weight(1f), clue.right)
            }

            is TripletClue<*, *, *> -> {
                DrawItem(modifier = Modifier.weight(1f), clue.a)
                DrawItem(modifier = Modifier.weight(1f), clue.b)
                DrawItem(modifier = Modifier.weight(1f), clue.c)
            }
        }
    }
}

@Composable
fun VerticalClue(modifier: Modifier = Modifier, clue: SameColumnClue<*, *>) {
    Column(modifier = modifier) {
        DrawItem(modifier = Modifier.weight(1f), clue.a)
        DrawItem(modifier = Modifier.weight(1f), clue.b)
    }
}