package com.jamshalat.app

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

class MainActivity : AudioServiceActivity() {
    companion object {
        private const val GEOMAGNETIC_CHANNEL = "com.jamshalat.app/geomagnetic"
        private const val SHARE_CHANNEL = "com.jamshalat.app/share"
        private const val DECLINATION_METHOD = "getDeclination"
        private const val SHARE_IMAGE_METHOD = "shareImage"
    }

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, GEOMAGNETIC_CHANNEL)
            .setMethodCallHandler(::handleGeomagneticMethodCall)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, SHARE_CHANNEL)
            .setMethodCallHandler(::handleShareMethodCall)
    }

    private fun handleGeomagneticMethodCall(call: MethodCall, result: MethodChannel.Result) {
        if (call.method != DECLINATION_METHOD) {
            result.notImplemented()
            return
        }

        val latitude = call.argument<Double>("latitude")
        val longitude = call.argument<Double>("longitude")
        if (latitude == null || longitude == null) {
            result.error("INVALID_ARGS", "Latitude and longitude are required.", null)
            return
        }

        val altitude = call.argument<Double>("altitude") ?: 0.0
        val timestamp = call.argument<Long>("timestamp") ?: System.currentTimeMillis()
        val field = GeomagneticField(
            latitude.toFloat(),
            longitude.toFloat(),
            altitude.toFloat(),
            timestamp,
        )
        result.success(field.declination.toDouble())
    }

    private fun handleShareMethodCall(call: MethodCall, result: MethodChannel.Result) {
        if (call.method != SHARE_IMAGE_METHOD) {
            result.notImplemented()
            return
        }

        val path = call.argument<String>("path")
        if (path.isNullOrBlank()) {
            result.error("INVALID_ARGS", "Path is required.", null)
            return
        }

        val file = File(path)
        if (!file.exists()) {
            result.error("FILE_NOT_FOUND", "Shared image file does not exist.", null)
            return
        }

        try {
            val mimeType = call.argument<String>("mimeType") ?: "image/png"
            val chooserTitle = call.argument<String>("chooserTitle")
            val authority = "${applicationContext.packageName}.flutter.share_provider"
            val fileUri = FileProvider.getUriForFile(this, authority, file)

            val shareIntent = Intent(Intent.ACTION_SEND).apply {
                type = mimeType
                putExtra(Intent.EXTRA_STREAM, fileUri)
                addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            }
            val chooserIntent = Intent.createChooser(shareIntent, chooserTitle)

            packageManager.queryIntentActivities(
                chooserIntent,
                PackageManager.MATCH_DEFAULT_ONLY,
            ).forEach { resolveInfo ->
                grantUriPermission(
                    resolveInfo.activityInfo.packageName,
                    fileUri,
                    Intent.FLAG_GRANT_READ_URI_PERMISSION,
                )
            }

            startActivity(chooserIntent)
            result.success(null)
        } catch (error: Throwable) {
            result.error("SHARE_FAILED", error.message, null)
        }
    }
}
