package com.pixelized.desktop.lwa.ui.screen.campaign.map

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Card
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.pixelized.desktop.lwa.ui.composable.scene.Scene
import com.pixelized.desktop.lwa.ui.composable.scene.cursor.onCursorControl
import com.pixelized.desktop.lwa.ui.composable.scene.debug.CameraDebugPanel
import com.pixelized.desktop.lwa.ui.composable.scene.debug.CursorDebugPanel
import com.pixelized.desktop.lwa.ui.composable.scene.debug.SceneDebugPanel
import com.pixelized.desktop.lwa.ui.theme.lwa
import kotlinx.coroutines.launch
import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.ic_center_focus_weak_24dp
import lwacharactersheet.composeapp.generated.resources.ic_frame_bug_24dp
import lwacharactersheet.composeapp.generated.resources.ic_visibility_24dp
import lwacharactersheet.composeapp.generated.resources.ic_zoom_in_map_24dp
import lwacharactersheet.composeapp.generated.resources.ic_zoom_out_map_24dp
import org.jetbrains.compose.resources.painterResource
import org.koin.compose.viewmodel.koinViewModel

@Composable
fun MapScene(
    modifier: Modifier = Modifier,
    viewModel: MapSceneViewModel = koinViewModel(),
) {
    val scope = rememberCoroutineScope()

    val camera by viewModel.camera.collectAsStateWithLifecycle()
    val scene by viewModel.scene.collectAsStateWithLifecycle()
    val openDebugMenu = viewModel.displayDebugMenu.collectAsStateWithLifecycle()
    val enableDebug = viewModel.enableDebug.collectAsStateWithLifecycle()
    val enableLayersToggle = viewModel.enableLayersToggle.collectAsStateWithLifecycle()

    Scene(
        modifier = Modifier
            .onCursorControl(camera = camera, cursor = viewModel.cursor)
            .then(other = modifier),
        scene = scene,
        camera = camera,
    ) {
        MapActions(
            modifier = Modifier
                .align(alignment = Alignment.BottomEnd)
                .padding(paddingValues = MaterialTheme.lwa.dimen.paddingValues),
            enableDebug = enableDebug,
            enableLayersToggle = enableLayersToggle,
            onZoomIn = {
                camera.zoom(power = 0.15f)
            },
            onZoomOut = {
                camera.zoom(power = -0.15f)
            },
            onResetCamera = {
                camera.resetPosition()
                camera.resetZoom()
            },
            onToggleLayer = {
                scope.launch {
                    scene.layers.drop(1).forEach {
                        it.alpha(alpha = if (it.alpha == 0f) 1f else 0f)
                    }
                }
            },
            onToggleDebug = viewModel::toggleDebugMenu,
        )

        AnimatedVisibility(
            modifier = Modifier.align(alignment = Alignment.TopEnd),
            visible = openDebugMenu.value,
        ) {
            Card(
                modifier = Modifier
                    .padding(paddingValues = MaterialTheme.lwa.dimen.paddingValues)
                    .verticalScroll(state = rememberScrollState()),
                backgroundColor = MaterialTheme.lwa.colorScheme.elevated.base4dp,
            ) {
                Column(
                    modifier = Modifier.padding(paddingValues = MaterialTheme.lwa.dimen.paddingValues),
                    verticalArrangement = Arrangement.spacedBy(space = 4.dp),
                ) {
                    SceneDebugPanel(
                        scene = scene,
                    )
                    CameraDebugPanel(
                        camera = camera,
                    )
                    CursorDebugPanel(
                        camera = camera,
                        cursors = remember { listOf(viewModel.cursor) },
                    )
                }
            }
        }
    }
}

@Composable
private fun MapActions(
    modifier: Modifier = Modifier,
    enableDebug: State<Boolean>,
    enableLayersToggle: State<Boolean>,
    onZoomIn: () -> Unit,
    onZoomOut: () -> Unit,
    onResetCamera: () -> Unit,
    onToggleLayer: () -> Unit,
    onToggleDebug: () -> Unit,
) {
    Row(
        modifier = modifier,
    ) {
        IconButton(
            onClick = onZoomIn,
        ) {
            Icon(
                painter = painterResource(Res.drawable.ic_zoom_in_map_24dp),
                contentDescription = null
            )
        }
        IconButton(
            onClick = onZoomOut,
        ) {
            Icon(
                painter = painterResource(Res.drawable.ic_zoom_out_map_24dp),
                contentDescription = null
            )
        }
        IconButton(
            onClick = onResetCamera,
        ) {
            Icon(
                painter = painterResource(Res.drawable.ic_center_focus_weak_24dp),
                contentDescription = null
            )
        }
        AnimatedVisibility(
            visible = enableLayersToggle.value,
            enter = fadeIn(),
            exit = fadeOut(),
        ) {
            IconButton(
                onClick = onToggleLayer,
            ) {
                Icon(
                    painter = painterResource(Res.drawable.ic_visibility_24dp),
                    contentDescription = null
                )
            }
        }
        AnimatedVisibility(
            visible = enableDebug.value,
            enter = fadeIn(),
            exit = fadeOut(),
        ) {
            IconButton(
                onClick = onToggleDebug,
            ) {
                Icon(
                    painter = painterResource(Res.drawable.ic_frame_bug_24dp),
                    contentDescription = null
                )
            }
        }
    }
}