package com.lazy.emulate.ui.screens.settings

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
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.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowRight
import androidx.compose.material.icons.filled.Bluetooth
import androidx.compose.material.icons.filled.BluetoothConnected
import androidx.compose.material.icons.filled.Gamepad
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Card
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.lazy.emulate.data.PreferencesManager
import com.lazy.emulate.emulation.ConsoleType
import com.lazy.emulate.input.ButtonMappingManager
import com.lazy.emulate.input.ControllerManager
import com.lazy.emulate.input.GameController
import com.lazy.emulate.input.GamepadButton
import com.lazy.emulate.input.OverlayVisibility

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ControllerSettingsScreen(
    controllerManager: ControllerManager,
    preferencesManager: PreferencesManager,
    buttonMappingManager: ButtonMappingManager,
    onBack: () -> Unit,
    onTestController: () -> Unit,
    onControllerLayout: (ConsoleType) -> Unit
) {
    val controllers by controllerManager.connectedControllers.collectAsState()
    val activeController by controllerManager.activeController.collectAsState()

    var overlayVisibility by remember { mutableStateOf(preferencesManager.overlayVisibility) }

    // Button remapping state
    var showRemapDialog by remember { mutableStateOf(false) }
    var remapConsole by remember { mutableStateOf(ConsoleType.PS1) }
    var remapButton by remember { mutableStateOf<GamepadButton?>(null) }
    var remapVersion by remember { mutableStateOf(0) }

    // Controller remap state
    var showControllerRemapDialog by remember { mutableStateOf(false) }
    var controllerRemapFrom by remember { mutableStateOf<GamepadButton?>(null) }
    var controllerRemapVersion by remember { mutableStateOf(0) }

    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("Controllers") },
                navigationIcon = {
                    IconButton(onClick = onBack) {
                        Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back")
                    }
                }
            )
        }
    ) { padding ->
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(padding)
                .verticalScroll(rememberScrollState())
                .padding(16.dp)
        ) {
            // Connected controllers
            Text("Devices", style = MaterialTheme.typography.titleLarge)
            Spacer(modifier = Modifier.height(12.dp))

            if (controllers.isEmpty()) {
                Card(modifier = Modifier.fillMaxWidth()) {
                    Row(
                        modifier = Modifier.padding(16.dp),
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Icon(
                            Icons.Default.Bluetooth,
                            contentDescription = null,
                            tint = MaterialTheme.colorScheme.onSurfaceVariant
                        )
                        Spacer(modifier = Modifier.width(12.dp))
                        Column {
                            Text(
                                "No controllers connected",
                                style = MaterialTheme.typography.bodyLarge
                            )
                            Text(
                                "Pair a Bluetooth controller in system settings",
                                style = MaterialTheme.typography.bodyMedium,
                                color = MaterialTheme.colorScheme.onSurfaceVariant
                            )
                        }
                    }
                }
            } else {
                Card(modifier = Modifier.fillMaxWidth()) {
                    controllers.forEachIndexed { index, controller ->
                        ControllerItem(
                            controller = controller,
                            isActive = controller.deviceId == activeController?.deviceId,
                            onClick = { controllerManager.setActiveController(controller) }
                        )
                        if (index < controllers.lastIndex) {
                            HorizontalDivider()
                        }
                    }
                }
            }

            Spacer(modifier = Modifier.height(12.dp))

            Card(
                modifier = Modifier
                    .fillMaxWidth()
                    .clickable(onClick = onTestController)
            ) {
                Row(
                    modifier = Modifier.padding(16.dp),
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Icon(
                        Icons.Default.Gamepad,
                        contentDescription = null,
                        tint = MaterialTheme.colorScheme.primary
                    )
                    Spacer(modifier = Modifier.width(12.dp))
                    Column {
                        Text("Test Controller", style = MaterialTheme.typography.bodyLarge)
                        Text(
                            "Live button tester and raw event log",
                            style = MaterialTheme.typography.bodyMedium,
                            color = MaterialTheme.colorScheme.onSurfaceVariant
                        )
                    }
                }
            }

            Spacer(modifier = Modifier.height(24.dp))

            // Touch Overlay
            Text("Touch Overlay", style = MaterialTheme.typography.titleLarge)
            Spacer(modifier = Modifier.height(12.dp))

            Card(modifier = Modifier.fillMaxWidth()) {
                Column(
                    modifier = Modifier
                        .fillMaxWidth()
                        .clickable {
                            overlayVisibility = overlayVisibility.next()
                            preferencesManager.overlayVisibility = overlayVisibility
                        }
                        .padding(16.dp)
                ) {
                    Text("Visibility", style = MaterialTheme.typography.bodyLarge)
                    Text(
                        overlayVisibility.label,
                        style = MaterialTheme.typography.bodyMedium,
                        color = MaterialTheme.colorScheme.onSurfaceVariant
                    )
                }
                HorizontalDivider()
                // Per-platform layout editors
                val implementedConsoles = ConsoleType.entries.filter { it.isImplemented }
                implementedConsoles.forEachIndexed { index, console ->
                    ListItem(
                        headlineContent = { Text("${console.displayName} Layout") },
                        trailingContent = {
                            Icon(
                                Icons.AutoMirrored.Filled.KeyboardArrowRight,
                                contentDescription = null
                            )
                        },
                        modifier = Modifier.clickable { onControllerLayout(console) }
                    )
                    if (index < implementedConsoles.lastIndex) {
                        HorizontalDivider()
                    }
                }
            }

            Spacer(modifier = Modifier.height(24.dp))

            // Controller Button Remap
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.SpaceBetween,
                verticalAlignment = Alignment.CenterVertically
            ) {
                Text("Controller Remap", style = MaterialTheme.typography.titleLarge)
                IconButton(onClick = {
                    buttonMappingManager.resetControllerRemaps()
                    controllerRemapVersion++
                }) {
                    Icon(Icons.Default.Refresh, contentDescription = "Reset remaps")
                }
            }
            Spacer(modifier = Modifier.height(4.dp))
            Text(
                "Remap physical controller buttons",
                style = MaterialTheme.typography.bodyMedium,
                color = MaterialTheme.colorScheme.onSurfaceVariant
            )
            Spacer(modifier = Modifier.height(12.dp))

            val controllerRemaps = remember(controllerRemapVersion) {
                buttonMappingManager.getControllerRemaps()
            }
            val controllerButtons = listOf(
                GamepadButton.FACE_BOTTOM, GamepadButton.FACE_RIGHT,
                GamepadButton.FACE_LEFT, GamepadButton.FACE_TOP,
                GamepadButton.L1, GamepadButton.R1, GamepadButton.L2, GamepadButton.R2,
                GamepadButton.START, GamepadButton.SELECT
            )

            Card(modifier = Modifier.fillMaxWidth()) {
                controllerButtons.forEachIndexed { index, button ->
                    val currentTarget = controllerRemaps[button]
                    Row(
                        modifier = Modifier
                            .fillMaxWidth()
                            .clickable {
                                controllerRemapFrom = button
                                showControllerRemapDialog = true
                            }
                            .padding(horizontal = 16.dp, vertical = 12.dp),
                        horizontalArrangement = Arrangement.SpaceBetween,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Text(
                            buttonDisplayName(button),
                            style = MaterialTheme.typography.bodyLarge
                        )
                        Text(
                            if (currentTarget != null) buttonDisplayName(currentTarget) else "Default",
                            style = MaterialTheme.typography.bodyMedium,
                            color = if (currentTarget != null)
                                MaterialTheme.colorScheme.primary
                            else
                                MaterialTheme.colorScheme.onSurfaceVariant
                        )
                    }
                    if (index < controllerButtons.lastIndex) {
                        HorizontalDivider()
                    }
                }
            }

            Spacer(modifier = Modifier.height(24.dp))

            // Button Mapping (per-console libretro mapping)
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.SpaceBetween,
                verticalAlignment = Alignment.CenterVertically
            ) {
                Text("Button Mapping", style = MaterialTheme.typography.titleLarge)
                IconButton(onClick = {
                    buttonMappingManager.resetToDefaults(remapConsole)
                    remapVersion++
                }) {
                    Icon(Icons.Default.Refresh, contentDescription = "Reset to defaults")
                }
            }
            Spacer(modifier = Modifier.height(4.dp))
            Text(
                "Map buttons to libretro IDs for ${remapConsole.displayName}",
                style = MaterialTheme.typography.bodyMedium,
                color = MaterialTheme.colorScheme.onSurfaceVariant
            )
            Spacer(modifier = Modifier.height(12.dp))

            val currentMapping = remember(remapVersion, remapConsole) {
                buttonMappingManager.getMapping(remapConsole)
            }
            val mappableButtons = listOf(
                GamepadButton.FACE_BOTTOM, GamepadButton.FACE_RIGHT,
                GamepadButton.FACE_LEFT, GamepadButton.FACE_TOP,
                GamepadButton.L1, GamepadButton.R1, GamepadButton.L2, GamepadButton.R2,
                GamepadButton.START, GamepadButton.SELECT
            )

            Card(modifier = Modifier.fillMaxWidth()) {
                mappableButtons.forEachIndexed { index, button ->
                    val retroId = currentMapping[button] ?: -1
                    val defaultId = buttonMappingManager.getDefaultMapping(remapConsole)[button] ?: -1
                    val isCustom = retroId != defaultId
                    Row(
                        modifier = Modifier
                            .fillMaxWidth()
                            .clickable {
                                remapButton = button
                                showRemapDialog = true
                            }
                            .padding(horizontal = 16.dp, vertical = 12.dp),
                        horizontalArrangement = Arrangement.SpaceBetween,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Text(
                            buttonDisplayName(button),
                            style = MaterialTheme.typography.bodyLarge
                        )
                        Text(
                            retroIdDisplayName(retroId),
                            style = MaterialTheme.typography.bodyMedium,
                            color = if (isCustom) MaterialTheme.colorScheme.primary
                            else MaterialTheme.colorScheme.onSurfaceVariant,
                            fontWeight = if (isCustom) FontWeight.Bold else FontWeight.Normal
                        )
                    }
                    if (index < mappableButtons.lastIndex) {
                        HorizontalDivider()
                    }
                }
            }
        }
    }

    // Button mapping dialog (libretro ID picker)
    if (showRemapDialog && remapButton != null) {
        val retroIds = listOf(
            0 to "B (Cross)", 1 to "Y (Square)", 2 to "Select", 3 to "Start",
            4 to "D-Up", 5 to "D-Down", 6 to "D-Left", 7 to "D-Right",
            8 to "A (Circle)", 9 to "X (Triangle)", 10 to "L1", 11 to "R1",
            12 to "L2", 13 to "R2", 14 to "L3", 15 to "R3"
        )
        AlertDialog(
            onDismissRequest = { showRemapDialog = false },
            title = { Text("Map ${buttonDisplayName(remapButton!!)}") },
            text = {
                Column {
                    Text(
                        "Select the libretro button to map to:",
                        style = MaterialTheme.typography.bodyMedium,
                        modifier = Modifier.padding(bottom = 8.dp)
                    )
                    retroIds.forEach { (id, name) ->
                        Text(
                            text = name,
                            modifier = Modifier
                                .fillMaxWidth()
                                .clickable {
                                    buttonMappingManager.setButtonMapping(remapConsole, remapButton!!, id)
                                    remapVersion++
                                    showRemapDialog = false
                                }
                                .padding(vertical = 10.dp, horizontal = 4.dp),
                            style = MaterialTheme.typography.bodyLarge
                        )
                    }
                }
            },
            confirmButton = {},
            dismissButton = {
                TextButton(onClick = { showRemapDialog = false }) {
                    Text("Cancel")
                }
            }
        )
    }

    // Controller remap dialog (button-to-button picker)
    if (showControllerRemapDialog && controllerRemapFrom != null) {
        val targetButtons = listOf(
            GamepadButton.FACE_BOTTOM, GamepadButton.FACE_RIGHT,
            GamepadButton.FACE_LEFT, GamepadButton.FACE_TOP,
            GamepadButton.L1, GamepadButton.R1, GamepadButton.L2, GamepadButton.R2,
            GamepadButton.L3, GamepadButton.R3,
            GamepadButton.DPAD_UP, GamepadButton.DPAD_DOWN,
            GamepadButton.DPAD_LEFT, GamepadButton.DPAD_RIGHT,
            GamepadButton.START, GamepadButton.SELECT
        )
        AlertDialog(
            onDismissRequest = { showControllerRemapDialog = false },
            title = { Text("Remap ${buttonDisplayName(controllerRemapFrom!!)}") },
            text = {
                Column {
                    Text(
                        "Select what this button should act as:",
                        style = MaterialTheme.typography.bodyMedium,
                        modifier = Modifier.padding(bottom = 8.dp)
                    )
                    targetButtons.forEach { target ->
                        Text(
                            text = buttonDisplayName(target),
                            modifier = Modifier
                                .fillMaxWidth()
                                .clickable {
                                    buttonMappingManager.setControllerRemap(controllerRemapFrom!!, target)
                                    controllerRemapVersion++
                                    showControllerRemapDialog = false
                                }
                                .padding(vertical = 10.dp, horizontal = 4.dp),
                            style = MaterialTheme.typography.bodyLarge
                        )
                    }
                }
            },
            confirmButton = {},
            dismissButton = {
                TextButton(onClick = { showControllerRemapDialog = false }) {
                    Text("Cancel")
                }
            }
        )
    }
}

private fun buttonDisplayName(button: GamepadButton): String {
    return when (button) {
        GamepadButton.FACE_BOTTOM -> "Cross / A"
        GamepadButton.FACE_RIGHT -> "Circle / B"
        GamepadButton.FACE_LEFT -> "Square / X"
        GamepadButton.FACE_TOP -> "Triangle / Y"
        GamepadButton.DPAD_UP -> "D-Pad Up"
        GamepadButton.DPAD_DOWN -> "D-Pad Down"
        GamepadButton.DPAD_LEFT -> "D-Pad Left"
        GamepadButton.DPAD_RIGHT -> "D-Pad Right"
        GamepadButton.L1 -> "L1"
        GamepadButton.R1 -> "R1"
        GamepadButton.L2 -> "L2"
        GamepadButton.R2 -> "R2"
        GamepadButton.L3 -> "L3"
        GamepadButton.R3 -> "R3"
        GamepadButton.START -> "Start"
        GamepadButton.SELECT -> "Select"
        GamepadButton.MODE -> "Mode"
        GamepadButton.Z_BUTTON -> "Z"
        GamepadButton.C_BUTTON -> "C"
    }
}

private fun retroIdDisplayName(id: Int): String {
    return when (id) {
        0 -> "B (Cross)"
        1 -> "Y (Square)"
        2 -> "Select"
        3 -> "Start"
        4 -> "D-Up"
        5 -> "D-Down"
        6 -> "D-Left"
        7 -> "D-Right"
        8 -> "A (Circle)"
        9 -> "X (Triangle)"
        10 -> "L1"
        11 -> "R1"
        12 -> "L2"
        13 -> "R2"
        14 -> "L3"
        15 -> "R3"
        else -> "Unknown ($id)"
    }
}

@Composable
private fun ControllerItem(
    controller: GameController,
    isActive: Boolean,
    onClick: () -> Unit
) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Icon(
            imageVector = if (isActive) Icons.Default.BluetoothConnected else Icons.Default.Gamepad,
            contentDescription = null,
            tint = if (isActive) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurfaceVariant
        )
        Spacer(modifier = Modifier.width(12.dp))
        Column(modifier = Modifier.weight(1f)) {
            Text(
                text = controller.name,
                style = MaterialTheme.typography.bodyLarge,
                color = if (isActive) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface
            )
            Text(
                text = if (isActive) "Active" else if (controller.isExternal) "Bluetooth" else "Built-in",
                style = MaterialTheme.typography.bodyMedium,
                color = MaterialTheme.colorScheme.onSurfaceVariant
            )
        }
    }
}
