package com.siro_driver.trip_overlay_plugin

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.provider.Settings
import android.util.Log
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.PluginRegistry

class TripOverlayPlugin :
        FlutterPlugin, MethodCallHandler, ActivityAware, PluginRegistry.ActivityResultListener {

    private lateinit var channel: MethodChannel
    private lateinit var context: Context
    private var activity: Activity? = null

    companion object {
        const val CHANNEL = "trip_overlay_plugin"

        const val TAG = "TripOverlayPlugin"
        const val REQUEST_CODE_OVERLAY = 1001

        // Static reference so TripOverlayService can call back into Flutter
        var methodChannel: MethodChannel? = null

        /**
         * Called by TripOverlayService when the driver taps Accept. Sends event Flutter → Dart
         * side.
         */
        fun notifyTripAccepted(tripId: String) {
            methodChannel?.invokeMethod("onTripAccepted", mapOf("tripId" to tripId))
            Log.d(TAG, "notifyTripAccepted: $tripId")
        }

        /** Called by TripOverlayService when the driver taps Reject or timer expires. */
        fun notifyTripRejected(tripId: String) {
            methodChannel?.invokeMethod("onTripRejected", mapOf("tripId" to tripId))
            Log.d(TAG, "notifyTripRejected: $tripId")
        }
    }

    // ─── FlutterPlugin ───────────────────────────────────────────────────────

    override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
        context = binding.applicationContext
        channel = MethodChannel(binding.binaryMessenger, CHANNEL)
        channel.setMethodCallHandler(this)
        methodChannel = channel
        Log.d(TAG, "Plugin attached to engine")
    }

    override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
        channel.setMethodCallHandler(null)
        methodChannel = null
    }

    // ─── MethodCallHandler ───────────────────────────────────────────────────

    override fun onMethodCall(call: MethodCall, result: Result) {
        when (call.method) {
            "isPermissionGranted" -> {
                result.success(isOverlayPermissionGranted())
            }
            "requestPermission" -> {
                requestOverlayPermission()
                result.success(null)
            }
            "showOverlay" -> {
                val tripDataJson =
                        call.argument<String>("tripData")
                                ?: run {
                                    result.error("INVALID_ARGS", "tripData is required", null)
                                    return
                                }
                val autoCloseSeconds = call.argument<Int>("autoCloseSeconds") ?: 30
                val success = showOverlay(tripDataJson, autoCloseSeconds)
                result.success(success)
            }
            "hideOverlay" -> {
                hideOverlay()
                result.success(null)
            }
            "isOverlayActive" -> {
                result.success(TripOverlayService.isRunning)
            }
            else -> result.notImplemented()
        }
    }

    // ─── Permission Helpers ───────────────────────────────────────────────────

    private fun isOverlayPermissionGranted(): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            Settings.canDrawOverlays(context)
        } else {
            true // Pre-M devices don't need runtime permission
        }
    }

    private fun requestOverlayPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val intent =
                    Intent(
                                    Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                                    Uri.parse("package:${context.packageName}")
                            )
                            .apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }
            activity?.startActivityForResult(intent, REQUEST_CODE_OVERLAY)
                    ?: context.startActivity(intent)
        }
    }

    // ─── Overlay Control ──────────────────────────────────────────────────────

    private fun showOverlay(tripDataJson: String, autoCloseSeconds: Int): Boolean {
        if (!isOverlayPermissionGranted()) {
            Log.w(TAG, "Overlay permission not granted")
            return false
        }
        val intent =
                Intent(context, TripOverlayService::class.java).apply {
                    action = TripOverlayService.ACTION_SHOW
                    putExtra(TripOverlayService.EXTRA_TRIP_DATA, tripDataJson)
                    putExtra(TripOverlayService.EXTRA_AUTO_CLOSE_SECONDS, autoCloseSeconds)
                }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(intent)
        } else {
            context.startService(intent)
        }
        Log.d(TAG, "showOverlay called with tripData: $tripDataJson")
        return true
    }

    private fun hideOverlay() {
        val intent =
                Intent(context, TripOverlayService::class.java).apply {
                    action = TripOverlayService.ACTION_HIDE
                }
        context.startService(intent)
        Log.d(TAG, "hideOverlay called")
    }

    // ─── ActivityAware ────────────────────────────────────────────────────────

    override fun onAttachedToActivity(binding: ActivityPluginBinding) {
        activity = binding.activity
        binding.addActivityResultListener(this)
    }

    override fun onDetachedFromActivityForConfigChanges() {
        activity = null
    }
    override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
        activity = binding.activity
    }
    override fun onDetachedFromActivity() {
        activity = null
    }

    // ─── ActivityResultListener ───────────────────────────────────────────────

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean {
        if (requestCode == REQUEST_CODE_OVERLAY) {
            Log.d(TAG, "Overlay permission result received")
            return true
        }
        return false
    }
}
