package com.pixelized.biblib.ui.screen.home.detail

import android.content.res.Configuration
import androidx.annotation.StringDef
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.RadioButton
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import com.pixelized.biblib.R
import com.pixelized.biblib.ui.composable.Handle
import com.pixelized.biblib.ui.theme.BibLibTheme
import com.pixelized.biblib.utils.extention.*

@Stable
@Immutable
data class OptionUio(
    val value: String,
    val selected: Boolean = false,
)

@Retention(AnnotationRetention.SOURCE)
@StringDef(Format.EPUB, Format.MOBI)
annotation class Format {
    companion object {
        const val EPUB = "epub"
        const val MOBI = "mobi"
    }
}

@Composable
fun DetailScreenSendOption(
    modifier: Modifier = Modifier,
    optionViewModel: BookOptionViewModel = hiltViewModel(),
    emails: List<String>,
    onHelp: (url: String) -> Unit,
    onSend: (email: String, format: String) -> Unit,
) {
    LaunchedEffect(key1 = emails) {
        optionViewModel.updateEmails(amazonEmails = emails)
    }
    DetailScreenSendOption(
        modifier = modifier,
        emails = optionViewModel.emails,
        formats = optionViewModel.formats,
        onEmail = { optionViewModel.selectMail(it.value) },
        onFormat = { optionViewModel.selectFormat(it.value) },
        onHelp = onHelp,
        onSend = onSend,
    )
}

@Composable
fun DetailScreenSendOption(
    modifier: Modifier = Modifier,
    emails: List<OptionUio>,
    formats: List<OptionUio>,
    onHelp: (url: String) -> Unit,
    onEmail: (OptionUio) -> Unit,
    onFormat: (OptionUio) -> Unit,
    onSend: (email: String, format: String) -> Unit,
) {
    val amazonHelpUri = stringResource(R.string.detail_send_confirm_help_url)

    LazyColumn(
        modifier = modifier.fillMaxWidth(),
    ) {
        item {
            Column(
                modifier = Modifier
                    .padding(top = 16.dp)
                    .padding(horizontal = 16.dp),
            ) {
                Handle(
                    modifier = Modifier
                        .align(alignment = CenterHorizontally)
                        .padding(bottom = 16.dp),
                )
                Text(
                    modifier = Modifier.padding(bottom = 16.dp),
                    style = MaterialTheme.typography.h6,
                    color = MaterialTheme.bibLib.colors.typography.medium,
                    text = stringResource(R.string.detail_send_confirm_title)
                )

                Text(
                    style = MaterialTheme.typography.caption,
                    color = MaterialTheme.bibLib.colors.typography.light,
                    text = rememberDescription()
                )

                Text(
                    modifier = Modifier
                        .clickable(onClick = { onHelp(amazonHelpUri) })
                        .padding(vertical = 8.dp),
                    textAlign = TextAlign.Center,
                    style = MaterialTheme.typography.caption,
                    color = MaterialTheme.bibLib.colors.typography.emphasis,
                    overflow = TextOverflow.Ellipsis,
                    maxLines = 1,
                    text = stringResource(R.string.detail_send_confirm_help),
                )
            }
        }

        item {
            Text(
                modifier = Modifier
                    .padding(vertical = 8.dp)
                    .padding(horizontal = 16.dp),
                color = MaterialTheme.bibLib.colors.typography.light,
                style = MaterialTheme.typography.caption,
                text = stringResource(id = R.string.detail_option_mail),
            )
        }
        items(items = emails) { email ->
            OptionItem(
                modifier = Modifier
                    .clickable { onEmail(email) }
                    .fillMaxWidth()
                    .padding(all = 16.dp),
                uio = email,
            )
        }
        item {
            Text(
                modifier = Modifier
                    .padding(vertical = 8.dp)
                    .padding(horizontal = 16.dp),
                color = MaterialTheme.bibLib.colors.typography.light,
                style = MaterialTheme.typography.caption,
                text = stringResource(id = R.string.detail_option_format),
            )
        }
        items(items = formats) { format ->
            OptionItem(
                modifier = Modifier
                    .clickable { onFormat(format) }
                    .fillMaxWidth()
                    .padding(all = 16.dp),
                uio = format,
            )
        }
        item {
            Button(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(horizontal = 16.dp),
                onClick = {
                    val format = formats.first { it.selected }
                    val email = emails.first { it.selected }
                    onSend(email.value, format.value)
                },
            ) {
                Text(
                    text = stringResource(id = R.string.detail_option_action)
                )
            }
        }
    }
}

@Composable
private fun OptionItem(
    modifier: Modifier = Modifier,
    uio: OptionUio,
) {
    Row(
        modifier = modifier,
        verticalAlignment = Alignment.CenterVertically,
    ) {
        RadioButton(
            selected = uio.selected,
            onClick = null,
        )
        Text(
            modifier = Modifier
                .padding(
                    start = 16.dp,
                    end = 8.dp,
                )
                .weight(1f),
            style = MaterialTheme.typography.body1,
            color = MaterialTheme.colors.onSurface,
            maxLines = 1,
            overflow = TextOverflow.Ellipsis,
            text = uio.value
        )
    }
}

@Composable
private fun rememberDescription(
    style: TextStyle = MaterialTheme.typography.caption,
): AnnotatedString {
    val email = stringResource(id = R.string.martin_sender)
    val description = stringResource(R.string.detail_send_confirm_description, email)
    return description.highlight(
        defaultStyle = style.toSpanStyle(),
        highlight = stringRegex(email),
    )
}

@Composable
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun DetailScreenEmailListPreview() {
    BibLibTheme {
        val emails by remember {
            mutableStateOf(
                listOf(
                    OptionUio("R.Giskard.Reventlov.Kindle@gmail.com", selected = true),
                    OptionUio("R.Daneel.Olivaw.Kindle@gmail.com"),
                )
            )
        }
        val formats by remember {
            mutableStateOf(
                listOf(
                    OptionUio(Format.EPUB.capitalize(), selected = true),
                    OptionUio(Format.MOBI.capitalize()),
                )
            )
        }
        DetailScreenSendOption(
            emails = emails,
            formats = formats,
            onHelp = { },
            onEmail = { },
            onFormat = { },
            onSend = { _, _ -> },
        )
    }
}