package com.isidroid.c23.ui.screen.render_preview._component

import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.sizeIn
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Icon
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Check
import androidx.compose.material.icons.rounded.Close
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.isidroid.c23.R
import com.isidroid.rendering.constant.PrintOrientation
import com.isidroid.rendering.constant.PrintSize
import com.isidroid.spot.model.PrintProfile
import com.isidroid.utils.asCost

@Composable
internal fun PrintSizeModalComponent(
    @PrintSize currentPrintSize: Int,
    onSelect: (Int) -> Unit,
    modifier: Modifier = Modifier,
) {
    val items: Array<Int> = arrayOf(PrintSize.PAPER_ORIGINAL_PAGE, PrintSize.FIT_TO_PRINTABLE_AREA, PrintSize.FIT_TO_PAPER, PrintSize.FILL_PAGE)
    OptionsModalComponent(
        title = R.string.print_setting_print_size,
        modifier = modifier,
        onCancel = { onSelect(currentPrintSize) },
    ) {
        for (size in items)
            PrintSizeItem(
                size = size,
                isCurrent = size == currentPrintSize,
                onSelect = onSelect,
                title = getPrintSizeTitle(size),
                image = getPrintSizeImage(size)
            )
    }
}

@Composable
internal fun PrintOrientationModalComponent(
    @PrintOrientation currentOrientation: Int,
    onSelect: (Int) -> Unit,
    modifier: Modifier = Modifier,
) {
    val items: Array<Int> = arrayOf(PrintOrientation.AUTO, PrintOrientation.PORTRAIT, PrintOrientation.LANDSCAPE)
    OptionsModalComponent(
        title = R.string.print_setting_page_orientation,
        modifier = modifier,
        onCancel = { onSelect(currentOrientation) },
    ) {
        for (item in items)
            PrintSizeItem(
                size = item,
                isCurrent = item == currentOrientation,
                onSelect = onSelect,
                title = getOrientationTitle(item),
                image = getOrientationImage(item)
            )
    }
}

@Composable
internal fun PrintCopiesModalComponent(
    copies: Int,
    onChange: (Boolean?) -> Unit,
    modifier: Modifier = Modifier,
) {
    OptionsModalComponent(
        title = R.string.print_setting_number_of_copies,
        modifier = modifier,
        onCancel = { onChange(null) },
    ) {
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.Center,
            verticalAlignment = Alignment.CenterVertically
        ) {
            ButtonCopy(text = "-", onClick = { onChange(false) })
            Text(
                text = "$copies",
                modifier = Modifier
                    .padding(horizontal = 24.dp)
                    .width(64.dp),
                fontWeight = FontWeight.Bold,
                fontSize = 18.sp,
                textAlign = TextAlign.Center
            )
            ButtonCopy(text = "+", onClick = { onChange(true) })
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun OptionsModalComponent(
    @StringRes title: Int,
    onCancel: () -> Unit,
    modifier: Modifier = Modifier,
    content: @Composable ColumnScope.() -> Unit
) {
    val sheetState = rememberModalBottomSheetState()

    ModalBottomSheet(
        onDismissRequest = { onCancel() },
        sheetState = sheetState,
        modifier = modifier.fillMaxWidth(),
    ) {
        Column(modifier = Modifier.fillMaxWidth()) {
            TopAppBar(
                title = { Text(text = stringResource(id = title)) },
                navigationIcon = { Icon(Icons.Rounded.Close, contentDescription = null, modifier = Modifier.clickable { onCancel() }) },
                modifier = Modifier.padding(horizontal = 8.dp)
            )

            content()
        }
    }
}

@Composable
private fun PrintSizeItem(
    size: Int,
    isCurrent: Boolean,
    onSelect: (Int) -> Unit,
    @StringRes title: Int,
    @DrawableRes image: Int,
    modifier: Modifier = Modifier
) {
    Row(
        verticalAlignment = Alignment.CenterVertically,
        modifier = modifier
            .fillMaxWidth()
            .clickable(!isCurrent) { onSelect(size) }
            .padding(vertical = 12.dp)
            .padding(horizontal = 20.dp)
    ) {
        Column(Modifier.width(40.dp), horizontalAlignment = Alignment.CenterHorizontally) {
            Image(
                painter = painterResource(id = image),
                contentDescription = null,
                modifier = Modifier.sizeIn(maxWidth = 36.dp, maxHeight = 27.dp),
            )
        }

        Text(
            text = stringResource(id = title),
            modifier = Modifier
                .weight(1f)
                .padding(horizontal = 12.dp),
            fontSize = 18.sp,
            fontWeight = FontWeight.Medium
        )

        if (isCurrent)
            Image(Icons.Rounded.Check, contentDescription = null, colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.error))

    }
}

@Composable
private fun ButtonCopy(text: String, onClick: () -> Unit) {
    OutlinedButton(
        onClick = onClick,
        shape = CircleShape,
        contentPadding = PaddingValues(0.dp),
        modifier = Modifier
            .size(52.dp)
            .border(2.dp, MaterialTheme.colorScheme.primary, CircleShape)
    ) { Text(text = text, fontSize = 20.sp) }
}


private fun getPrintSizeTitle(@PrintSize size: Int) = when (size) {
    PrintSize.PAPER_ORIGINAL_PAGE -> R.string.print_size_original
    PrintSize.FIT_TO_PRINTABLE_AREA -> R.string.print_size_printable_area
    PrintSize.FIT_TO_PAPER -> R.string.print_size_fit_to_paper
    PrintSize.FILL_PAGE -> R.string.print_size_fill_page
    else -> throw IllegalStateException()
}

private fun getPrintSizeImage(@PrintSize size: Int) = when (size) {
    PrintSize.PAPER_ORIGINAL_PAGE -> R.drawable.ic_option_printsize_actual
    PrintSize.FIT_TO_PRINTABLE_AREA -> R.drawable.ic_option_printsize_fit_to_printable
    PrintSize.FIT_TO_PAPER -> R.drawable.ic_option_printsize_fill_to_paper
    PrintSize.FILL_PAGE -> R.drawable.ic_option_printsize_fill_to_paper
    else -> throw IllegalStateException()
}

private fun getOrientationTitle(@PrintOrientation size: Int) = when (size) {
    PrintOrientation.AUTO -> R.string.orientation_auto
    PrintOrientation.PORTRAIT -> R.string.portrait
    PrintOrientation.LANDSCAPE -> R.string.landscape
    else -> throw IllegalStateException()
}

private fun getOrientationImage(@PrintOrientation size: Int) = when (size) {
    PrintOrientation.AUTO -> R.drawable.ic_option_auto_orientation
    PrintOrientation.PORTRAIT -> R.drawable.ic_option_portrait
    PrintOrientation.LANDSCAPE -> R.drawable.ic_option_landscape
    else -> throw IllegalStateException()
}

@Composable
internal fun PrintProfileListSelectorComponent(
    list: List<PrintProfile>,
    current: PrintProfile?,
    onChange: (String?) -> Unit,
    modifier: Modifier = Modifier
) {
    OptionsModalComponent(
        title = R.string.print_setting_number_of_copies,
        modifier = modifier,
        onCancel = { onChange(null) },
    ) {
        LazyColumn(
            modifier = Modifier.fillMaxWidth(),
        ) {
            items(list) { item ->
                val isCurrent = item == current

                Row(
                    verticalAlignment = Alignment.CenterVertically,
                    modifier = modifier
                        .fillMaxWidth()
                        .clickable(!isCurrent) { onChange(item.id) }
                        .padding(vertical = 12.dp)
                        .padding(horizontal = 20.dp)
                ) {
                    Text(
                        text = "${item.name}, ${item.cost.asCost()}",
                        modifier = Modifier
                            .weight(1f)
                            .padding(horizontal = 12.dp),
                        fontSize = 18.sp,
                    )

                    if (isCurrent)
                        Image(Icons.Rounded.Check, contentDescription = null, colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.error))
                }
            }
        }
    }
}


@Preview
@Composable
private fun PrintSizeModalComponentPreview() {
    Surface {
        val items: Array<Int> = arrayOf(PrintOrientation.AUTO, PrintOrientation.PORTRAIT, PrintOrientation.LANDSCAPE)
        Column {
            for (size in items)
                PrintSizeItem(
                    size = size,
                    isCurrent = size == PrintOrientation.PORTRAIT,
                    onSelect = {},
                    title = getOrientationTitle(size),
                    image = getOrientationImage(size)
                )
        }
    }
}


@Preview
@Composable
private fun ButtonsPreview() {
    Surface {
        Row {
            ButtonCopy(text = "+", onClick = { })
            ButtonCopy(text = "-", onClick = { })
        }
    }
}