package aza.instant

import android.Manifest
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Picture
import android.media.MediaScannerConnection
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.OpenableColumns
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.Canvas
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.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
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.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat
import androidx.core.graphics.withTranslation
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.workDataOf
import aza.instant.ui.theme.ProjectInstantTheme
import kotlinx.coroutines.launch
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader

class MainActivity : ComponentActivity() {
    private var sharedImageUri by mutableStateOf<Uri?>(null)
    private var isUriHandled = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        handleIntent(intent)

        setContent {
            ProjectInstantTheme {
                Scaffold(modifier = Modifier.fillMaxSize()) {
                    FileListerScreen(modifier = Modifier.padding(it), sharedImageUri = if (isUriHandled) null else sharedImageUri, onSharedImageHandled = { isUriHandled = true })
                }
            }
        }
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        setIntent(intent)
        isUriHandled = false
        handleIntent(intent)
    }

    private fun handleIntent(intent: Intent?) {
        if (intent?.action == Intent.ACTION_SEND && intent.type?.startsWith("image/") == true) {
            sharedImageUri = intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java)
        }
    }
}

@Composable
fun FileListerScreen(modifier: Modifier = Modifier, sharedImageUri: Uri?, onSharedImageHandled: () -> Unit) {
    var feedbackText by remember { mutableStateOf("Click a button to see the output here.") }
    var picture by remember { mutableStateOf<Picture?>(null) }
    val scrollState = rememberScrollState()
    val coroutineScope = rememberCoroutineScope()
    val context = LocalContext.current

    val askPerm = rememberLauncherForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
        feedbackText = "Permissions: ${it.entries.joinToString(", ")}"
    }

    LaunchedEffect(Unit) {
        mutableListOf(Manifest.permission.POST_NOTIFICATIONS, Manifest.permission.READ_MEDIA_IMAGES)
            .filter { ContextCompat.checkSelfPermission(context, it) != PackageManager.PERMISSION_GRANTED }
            .toTypedArray().ifEmpty { null }?.let { askPerm.launch(it) }
    }

    val renderAndUpload = { imagePath: String, originalFileName: String ->
        coroutineScope.launch {
            try {
                feedbackText = "Rendering..."
                val outDir = File("/storage/emulated/0/DCIM/CA_IMAGES_OUT/")
                val templateStream = context.resources.openRawResource(R.raw.postcard4)
                val template = BufferedReader(InputStreamReader(templateStream)).readText()
                val (svg, exif) = genSvg(template, imagePath)
                val (pic, bytes) = renderSvgBytes(context, svg, exif) ?: return@launch
                picture = pic

                // Save picture to file
                outDir.mkdirs()
                val out = File(outDir, "${File(originalFileName).nameWithoutExtension}-framed.jpg")
                    .apply { writeBytes(bytes) }

                MediaScannerConnection.scanFile(context, arrayOf(out.absolutePath), null, null)

                feedbackText = "Rendered ${originalFileName}, now uploading..."

                val uploadWorkRequest = OneTimeWorkRequestBuilder<UploadWorker>()
                    .setInputData(workDataOf(
                        "originalPhotoPath" to imagePath,
                        "editedPhotoPath" to out.absolutePath,
                        "urlName" to exif.urlName
                    ))
                    .build()
                WorkManager.getInstance(context).enqueue(uploadWorkRequest)

                // Launch Canon app
                context.startActivity(Intent().apply {
                    setClassName("jp.co.canon.ic.photolayout", "jp.co.canon.ic.photolayout.MainActivity")
                    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                })
            } catch (e: Exception) {
                feedbackText = "Error during operation: ${e.message}"
                Log.e("MainActivity", "Error during render or upload", e)
            }
        }
    }

    LaunchedEffect(sharedImageUri) {
        if (sharedImageUri == null) return@LaunchedEffect

        feedbackText = "Handling shared image..."
        val fileName = getFileName(context, sharedImageUri) ?: "shared_image_${System.currentTimeMillis()}.jpg"
        val tempFile = File(context.cacheDir, fileName)
        try {
            context.contentResolver.openInputStream(sharedImageUri)?.use { input ->
                tempFile.outputStream().use { output -> input.copyTo(output) }
            }
            renderAndUpload(tempFile.absolutePath, fileName)
            onSharedImageHandled()
        } catch (e: Exception) {
            feedbackText = "Failed to handle shared image: ${e.message}"
            Log.e("MainActivity", "Error handling shared image", e)
        }
    }

    Column(modifier = modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally) {
        Column(modifier = Modifier.weight(1f), horizontalAlignment = Alignment.CenterHorizontally) {
            picture?.let { p ->
                Canvas(modifier = Modifier.fillMaxWidth().weight(1f).drawWithCache {
                    onDrawWithContent {
                        drawIntoCanvas { canvas ->
                            if (!(p.width > 0 && p.height > 0)) return@onDrawWithContent
                            val scale = minOf(size.width / p.width, size.height / p.height)
                            val dx = (size.width - p.width * scale) / 2
                            val dy = (size.height - p.height * scale) / 2

                            canvas.nativeCanvas.withTranslation(dx, dy) {
                                scale(scale, scale)
                                drawPicture(p)
                            }
                        }
                    }
                }) {}
            }

            Text(text = feedbackText, modifier = Modifier.weight(1f).fillMaxWidth().padding(horizontal = 16.dp).verticalScroll(scrollState))
        }

        Row(modifier = Modifier.padding(16.dp)) {
            Button(onClick = { feedbackText = listFilesFromDcim() }) {
                Text(text = "List Files")
            }
            Spacer(modifier = Modifier.width(8.dp))
            Button(onClick = {
                coroutineScope.launch {
                    val imageDir = File("/storage/emulated/0/DCIM/CA_IMAGES/")
                    val latestImg = imageDir.listFiles()
                        ?.filter { !it.name.contains("-framed") && !it.name.contains(".trashed") }
                        ?.maxByOrNull { it.lastModified() }
                    if (latestImg == null) {
                        feedbackText = "No images found in CA_IMAGES"
                        return@launch
                    }
                    renderAndUpload(latestImg.absolutePath, latestImg.name)
                }
            }) { Text(text = "Render Latest") }
        }
    }
}

private fun getFileName(context: Context, uri: Uri): String? {
    context.contentResolver.query(uri, null, null, null, null)?.use { cursor ->
        if (cursor.moveToFirst()) {
            val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
            if (nameIndex != -1) return cursor.getString(nameIndex)
        }
    }
    return uri.path?.substringAfterLast('/')
}


private fun listFilesFromDcim(): String {
    val d = File("/storage/emulated/0/DCIM/CA_IMAGES/")
    if (!d.exists() || !d.isDirectory) return "Directory not found or is not a directory: ${d.absolutePath}"
    return d.listFiles()?.let { files ->
        files.ifEmpty { null }?.sortedBy { it.lastModified() }?.joinToString("\n") { it.name }
            ?: "No files found in ${d.absolutePath}"
    } ?: "Failed to list files in ${d.absolutePath}. listFiles() returned null."
}

@Preview(showBackground = true)
@Composable
fun FileListerScreenPreview() {
    ProjectInstantTheme {
        FileListerScreen(sharedImageUri = null, onSharedImageHandled = {})
    }
}
