package eu.geyskens.pdfscan.ui.screens

import android.content.Intent
import androidx.core.content.FileProvider
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.material.icons.Icons
import androidx.compose.material.icons.filled.Share
import androidx.compose.material.icons.filled.CloudUpload
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SegmentedButton
import androidx.compose.material3.SegmentedButtonDefaults
import androidx.compose.material3.SingleChoiceSegmentedButtonRow
import androidx.compose.material3.Text
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.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import eu.geyskens.pdfscan.R
import eu.geyskens.pdfscan.Routes
import eu.geyskens.pdfscan.ScanViewModel
import eu.geyskens.pdfscan.paperless.PaperlessClient
import eu.geyskens.pdfscan.pdf.PageSizeMode
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ExportScreen(vm: ScanViewModel, navController: NavController) {
    val context = LocalContext.current
    val scope = rememberCoroutineScope()
    val settings by vm.settings.collectAsState()
    val pages by vm.pages.collectAsState()

    val defaultName = remember {
        "scan_" + SimpleDateFormat("yyyyMMdd_HHmm", Locale.getDefault()).format(Date())
    }
    var fileName by remember { mutableStateOf(defaultName) }
    var a4 by remember { mutableStateOf(true) }
    var busy by remember { mutableStateOf(false) }
    var uploading by remember { mutableStateOf(false) }
    var uploadJob by remember { mutableStateOf<Job?>(null) }
    var status by remember { mutableStateOf<String?>(null) }

    fun mode() = if (a4) PageSizeMode.A4 else PageSizeMode.ORIGINAL

    Scaffold(
        topBar = { TopAppBar(title = { Text(stringResource(R.string.export_title, pages.size)) }) },
    ) { padding ->
        Column(
            Modifier.fillMaxSize().padding(padding).padding(16.dp),
            verticalArrangement = Arrangement.spacedBy(16.dp),
        ) {
            OutlinedTextField(
                value = fileName,
                onValueChange = { fileName = it },
                label = { Text(stringResource(R.string.file_name)) },
                singleLine = true,
                modifier = Modifier.fillMaxWidth(),
            )

            SingleChoiceSegmentedButtonRow(Modifier.fillMaxWidth()) {
                SegmentedButton(
                    selected = a4,
                    onClick = { a4 = true },
                    shape = SegmentedButtonDefaults.itemShape(0, 2),
                ) { Text(stringResource(R.string.page_size_a4)) }
                SegmentedButton(
                    selected = !a4,
                    onClick = { a4 = false },
                    shape = SegmentedButtonDefaults.itemShape(1, 2),
                ) { Text(stringResource(R.string.page_size_original)) }
            }

            Button(
                onClick = {
                    if (busy) return@Button
                    busy = true
                    status = null
                    scope.launch {
                        try {
                            val pdf = vm.exportPdf(fileName, mode())
                            val uri = FileProvider.getUriForFile(
                                context, "${context.packageName}.fileprovider", pdf
                            )
                            val share = Intent(Intent.ACTION_SEND).apply {
                                type = "application/pdf"
                                putExtra(Intent.EXTRA_STREAM, uri)
                                addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                            }
                            context.startActivity(Intent.createChooser(share, context.getString(R.string.share_pdf)))
                        } catch (e: Exception) {
                            status = context.getString(R.string.export_failed, e.message ?: "")
                        } finally {
                            busy = false
                        }
                    }
                },
                enabled = !busy,
                modifier = Modifier.fillMaxWidth(),
            ) {
                Icon(Icons.Filled.Share, contentDescription = null)
                Spacer(Modifier.width(8.dp))
                Text(stringResource(R.string.share_save))
            }

            Button(
                onClick = {
                    if (busy) return@Button
                    busy = true
                    uploading = true
                    status = null
                    uploadJob = scope.launch {
                        try {
                            val pdf = vm.exportPdf(fileName, mode())
                            when (val r = vm.uploadToPaperless(pdf, fileName)) {
                                is PaperlessClient.Result.Success ->
                                    status = context.getString(R.string.upload_added)
                                is PaperlessClient.Result.Duplicate ->
                                    status = context.getString(R.string.upload_duplicate)
                                is PaperlessClient.Result.Pending ->
                                    status = context.getString(R.string.upload_pending)
                                is PaperlessClient.Result.Failure ->
                                    status = r.message
                            }
                        } catch (e: CancellationException) {
                            // User tapped "Don't wait": the document was already sent.
                            status = context.getString(R.string.upload_background)
                        } catch (e: Exception) {
                            status = context.getString(R.string.error_generic, e.message ?: "")
                        } finally {
                            busy = false
                            uploading = false
                        }
                    }
                },
                enabled = !busy && settings.paperlessUrl.isNotBlank() && settings.hasToken,
                modifier = Modifier.fillMaxWidth(),
            ) {
                Icon(Icons.Filled.CloudUpload, contentDescription = null)
                Spacer(Modifier.width(8.dp))
                Text(stringResource(R.string.upload_to_paperless))
            }

            if (!settings.paperlessUrl.isNotBlank() || !settings.hasToken) {
                Text(
                    stringResource(R.string.paperless_not_configured),
                    style = androidx.compose.material3.MaterialTheme.typography.bodySmall,
                    color = Color(0xFF9A9A9A),
                )
                OutlinedButton(
                    onClick = { navController.navigate(Routes.SETTINGS) },
                    modifier = Modifier.fillMaxWidth(),
                ) { Text(stringResource(R.string.set_up_paperless)) }
            }

            if (busy) {
                Row(verticalAlignment = androidx.compose.ui.Alignment.CenterVertically) {
                    CircularProgressIndicator(Modifier.height(24.dp))
                    Spacer(Modifier.width(12.dp))
                    Text(if (uploading) stringResource(R.string.uploading) else stringResource(R.string.working))
                    if (uploading) {
                        Spacer(Modifier.width(12.dp))
                        OutlinedButton(onClick = { uploadJob?.cancel() }) { Text(stringResource(R.string.dont_wait)) }
                    }
                }
            }
            status?.let { Text(it, color = Color(0xFF1F6FEB)) }
        }
    }
}
