package com.futo.platformplayer.activities

import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.widget.EditText
import android.widget.ImageButton
import android.widget.LinearLayout
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.futo.platformplayer.R
import com.futo.platformplayer.UIDialogs
import com.futo.platformplayer.logging.Logger
import com.futo.platformplayer.polycentric.PolycentricStorage
import com.futo.platformplayer.setNavigationBarColorAndIcons
import com.futo.platformplayer.states.StateApp
import com.futo.platformplayer.states.StatePolycentric
import com.futo.platformplayer.views.overlays.LoaderOverlay
import com.futo.polycentric.core.ApiMethods
import com.futo.polycentric.core.KeyPair
import com.futo.polycentric.core.Process
import com.futo.polycentric.core.ProcessSecret
import com.futo.polycentric.core.SignedEvent
import com.futo.polycentric.core.Store
import com.futo.polycentric.core.base64UrlToByteArray
import com.google.zxing.integration.android.IntentIntegrator
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import userpackage.Protocol
import userpackage.Protocol.ExportBundle

class PolycentricImportProfileActivity : AppCompatActivity() {
    private lateinit var _buttonHelp: ImageButton
    private lateinit var _buttonScanProfile: LinearLayout
    private lateinit var _buttonImportFile: LinearLayout
    private lateinit var _buttonImportProfile: LinearLayout
    private lateinit var _editProfile: EditText
    private lateinit var _loaderOverlay: LoaderOverlay

    private val _qrCodeResultLauncher =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
                val scanResult =
                        IntentIntegrator.parseActivityResult(result.resultCode, result.data)
                scanResult?.let {
                    if (it.contents != null) {
                        val scannedUrl = it.contents
                        import(scannedUrl)
                    }
                }
            }

    private val _filePickerLauncher =
            registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
                uri?.let { fileUri ->
                    try {
                        // Check file size before reading
                        val fileSize =
                                contentResolver.openFileDescriptor(fileUri, "r")?.statSize ?: 0
                        val maxFileSize = 10 * 1024 * 1024 // 10MB limit

                        if (fileSize > maxFileSize) {
                            UIDialogs.toast(this, "File too large. Maximum size is 10MB.")
                            return@let
                        }

                        if (fileSize == 0L) {
                            UIDialogs.toast(this, "Selected file is empty.")
                            return@let
                        }

                        val content =
                                contentResolver
                                        .openInputStream(fileUri)
                                        ?.bufferedReader()
                                        ?.readText()
                        content?.let { fileContent ->
                            val trimmedContent = fileContent.trim()

                            // Check if content is empty after trimming
                            if (trimmedContent.isEmpty()) {
                                UIDialogs.toast(this, "Selected file contains no data.")
                                return@let
                            }

                            // Check if content looks like a valid polycentric URL
                            if (!trimmedContent.startsWith("polycentric://")) {
                                UIDialogs.toast(
                                        this,
                                        "Selected file does not contain a valid polycentric profile URL."
                                )
                                return@let
                            }

                            import(trimmedContent)
                        }
                                ?: run { UIDialogs.toast(this, "Could not read file content.") }
                    } catch (e: SecurityException) {
                        Logger.e(TAG, "Security exception reading file", e)
                        UIDialogs.toast(this, "Permission denied to read file.")
                    } catch (e: OutOfMemoryError) {
                        Logger.e(TAG, "Out of memory reading file", e)
                        UIDialogs.toast(this, "File too large to process.")
                    } catch (e: Exception) {
                        Logger.e(TAG, "Failed to read file", e)
                        UIDialogs.toast(this, "Failed to read file: ${e.message}")
                    }
                }
            }

    override fun attachBaseContext(newBase: Context?) {
        super.attachBaseContext(StateApp.instance.getLocaleContext(newBase))
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_polycentric_import_profile)
        setNavigationBarColorAndIcons()

        _buttonHelp = findViewById(R.id.button_help)
        _buttonScanProfile = findViewById(R.id.button_scan_profile)
        _buttonImportFile = findViewById(R.id.button_import_file)
        _buttonImportProfile = findViewById(R.id.button_import_profile)
        _loaderOverlay = findViewById(R.id.loader_overlay)
        _editProfile = findViewById(R.id.edit_profile)
        findViewById<ImageButton>(R.id.button_back).setOnClickListener { finish() }

        _buttonHelp.setOnClickListener {
            startActivity(Intent(this, PolycentricWhyActivity::class.java))
        }

        _buttonScanProfile.setOnClickListener {
            val integrator = IntentIntegrator(this)
            integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE)
            integrator.setPrompt(getString(R.string.scan_a_qr_code))
            integrator.setOrientationLocked(true)
            integrator.setCameraId(0)
            integrator.setBeepEnabled(false)
            integrator.setBarcodeImageEnabled(true)
            integrator.setCaptureActivity(QRCaptureActivity::class.java)
            _qrCodeResultLauncher.launch(integrator.createScanIntent())
        }

        _buttonImportFile.setOnClickListener { _filePickerLauncher.launch("text/plain") }

        _buttonImportProfile.setOnClickListener {
            if (_editProfile.text.isEmpty()) {
                UIDialogs.toast(this, getString(R.string.text_field_does_not_contain_any_data))
                return@setOnClickListener
            }

            import(_editProfile.text.toString())
        }

        val url = intent.getStringExtra("url")
        if (url != null) {
            import(url)
        }
    }

    private fun import(url: String) {
        if (!url.startsWith("polycentric://")) {
            UIDialogs.toast(this, getString(R.string.not_a_valid_url))
            return
        }

        _loaderOverlay.show()

        lifecycleScope.launch(Dispatchers.IO) {
            try {
                val data = url.substring("polycentric://".length).base64UrlToByteArray()
                val urlInfo = Protocol.URLInfo.parseFrom(data)

                if (urlInfo.urlType != 3L) {
                    throw Exception("Expected urlInfo struct of type ExportBundle")
                }

                val exportBundle = ExportBundle.parseFrom(urlInfo.body)
                val keyPair = KeyPair.fromProto(exportBundle.keyPair)

                val existingProcessSecret = Store.instance.getProcessSecret(keyPair.publicKey)
                if (existingProcessSecret != null) {
                    withContext(Dispatchers.Main) {
                        UIDialogs.toast(
                                this@PolycentricImportProfileActivity,
                                getString(R.string.this_profile_is_already_imported)
                        )
                    }
                    return@launch
                }

                val processSecret = ProcessSecret(keyPair, Process.random())
                Store.instance.addProcessSecret(processSecret)

                try {
                    PolycentricStorage.instance.addProcessSecret(processSecret)
                } catch (e: Throwable) {
                    Logger.e(TAG, "Failed to save process secret to secret storage.", e)
                }

                val processHandle = processSecret.toProcessHandle()

                for (e in exportBundle.events.eventsList) {
                    try {
                        val se = SignedEvent.fromProto(e)
                        Store.instance.putSignedEvent(se)
                    } catch (e: Throwable) {
                        Logger.w(TAG, "Ignored invalid event", e)
                    }
                }

                StatePolycentric.instance.setProcessHandle(processHandle)
                processHandle.fullyBackfillClient(ApiMethods.SERVER)
                withContext(Dispatchers.Main) {
                    startActivity(
                            Intent(
                                    this@PolycentricImportProfileActivity,
                                    PolycentricProfileActivity::class.java
                            )
                    )
                    finish()
                }
            } catch (e: Throwable) {
                Logger.w(TAG, "Failed to import profile", e)
                withContext(Dispatchers.Main) {
                    UIDialogs.toast(
                            this@PolycentricImportProfileActivity,
                            getString(R.string.failed_to_import_profile) + " '${e.message}'"
                    )
                }
            } finally {
                withContext(Dispatchers.Main) { _loaderOverlay.hide() }
            }
        }
    }

    companion object {
        private const val TAG = "PolycentricImportProfileActivity"
    }
}
