package com.fabledsword.minstrel

import android.content.Intent
import androidx.core.content.FileProvider
import com.ryanheise.audioservice.AudioServiceActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import java.io.File

// Must extend AudioServiceActivity (not FlutterActivity) so the
// audio_service plugin can wire its FlutterEngine through. Without this
// the platform call from AudioService.init() throws PlatformException
// "The Activity class declared in your AndroidManifest.xml is wrong",
// which on first start cascades into a flutter_cache_manager sqlite
// EXCLUSIVE-lock crash because the engine partially re-initialises.
class MainActivity : AudioServiceActivity() {

    companion object {
        private const val INSTALLER_CHANNEL = "com.fabledsword.minstrel/installer"
    }

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        // In-app update channel (#397). Dart calls install(path) with
        // the cache-dir APK path; we hand it to Android's
        // PackageInstaller via FileProvider + ACTION_VIEW.
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, INSTALLER_CHANNEL)
            .setMethodCallHandler { call, result ->
                when (call.method) {
                    "install" -> {
                        val path = call.argument<String>("path")
                        if (path == null) {
                            result.error("missing_path", "path argument required", null)
                            return@setMethodCallHandler
                        }
                        try {
                            installApk(path)
                            result.success(null)
                        } catch (e: Exception) {
                            result.error("install_failed", e.message, null)
                        }
                    }
                    else -> result.notImplemented()
                }
            }
    }

    private fun installApk(path: String) {
        val file = File(path)
        if (!file.exists()) {
            throw IllegalStateException("apk not found at $path")
        }
        val uri = FileProvider.getUriForFile(
            this,
            "${packageName}.fileprovider",
            file
        )
        val intent = Intent(Intent.ACTION_VIEW).apply {
            setDataAndType(uri, "application/vnd.android.package-archive")
            // NEW_TASK: PackageInstaller runs in its own task.
            // GRANT_READ_URI_PERMISSION: hands the content:// URI to
            // the installer process, which lacks our app's read perms
            // by default.
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or
                Intent.FLAG_GRANT_READ_URI_PERMISSION
        }
        startActivity(intent)
    }
}
