package com.nearle.partner

import android.app.AlarmManager
import android.app.PendingIntent
import android.app.PictureInPictureParams
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.content.res.Configuration
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.util.Rational
import androidx.core.view.WindowCompat
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import java.util.Calendar

class MainActivity : FlutterActivity() {
    private val channelName = "nearle/pip"
    private val shiftEndChannelName = "nearle/shift_end"

    // PiP tracking for safe exit on resume
    private val PREFS = "app_prefs"
    private val KEY_WAS_IN_PIP = "was_in_pip"
    private val handler = Handler(Looper.getMainLooper())

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // No automatic PiP entry here – only from explicit Flutter calls
    }

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

        // Enable edge-to-edge for Android 15+ (SDK 35+)
        if (Build.VERSION.SDK_INT >= 35) {
            WindowCompat.setDecorFitsSystemWindows(window, false)
        }

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, channelName)
            .setMethodCallHandler { call, result ->
                when (call.method) {
                    "enterPip" -> {
                        try {
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                                val aspect = Rational(16, 9)
                                val params = PictureInPictureParams.Builder()
                                    .setAspectRatio(aspect)
                                    .build()
                                enterPictureInPictureMode(params)
                            } else {
                                @Suppress("DEPRECATION")
                                enterPictureInPictureMode()
                            }
                            result.success(true)
                        } catch (e: Exception) {
                            result.error("PIP_ERROR", e.message, null)
                        }
                    }
                    "moveToBack" -> {
                        try {
                            moveTaskToBack(true)
                            result.success(true)
                        } catch (e: Exception) {
                            result.error("MOVE_BACK_ERROR", e.message, null)
                        }
                    }
                    "hasActiveDeliveries" -> {
                        try {
                            val hasActive = checkActiveDeliveries()
                            result.success(hasActive)
                        } catch (e: Exception) {
                            result.error("CHECK_ACTIVE_ERROR", e.message, null)
                        }
                    }
                    "ensureExitPip" -> {
                        try {
                            ensureExitPip()
                            result.success(true)
                        } catch (e: Exception) {
                            result.error("ENSURE_EXIT_PIP_ERROR", e.message, null)
                        }
                    }
                    else -> result.notImplemented()
                }
            }
        
        // Shift end alarm channel
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, shiftEndChannelName)
            .setMethodCallHandler { call, result ->
                when (call.method) {
                    "scheduleShiftEndAlarm" -> {
                        try {
                            val endTimeStr = call.argument<String>("endTime") ?: ""
                            val startTimeStr = call.argument<String>("startTime") ?: ""
                            if (endTimeStr.isNotEmpty()) {
                                scheduleShiftEndAlarm(endTimeStr, startTimeStr)
                                result.success(true)
                            } else {
                                result.error("INVALID_TIME", "End time is required", null)
                            }
                        } catch (e: Exception) {
                            result.error("ALARM_ERROR", e.message, null)
                        }
                    }
                    "cancelShiftEndAlarm" -> {
                        try {
                            cancelShiftEndAlarm()
                            result.success(true)
                        } catch (e: Exception) {
                            result.error("CANCEL_ERROR", e.message, null)
                        }
                    }
                    "handleShiftEnd" -> {
                        try {
                            // This is called by the BroadcastReceiver
                            // We need to call Flutter code to create break log
                            // Since we're in MainActivity, we can use the existing Flutter engine
                            // But the receiver might not have access to it, so we'll handle it differently
                            // The receiver will directly call the background service method
                            result.success(true)
                        } catch (e: Exception) {
                            result.error("HANDLE_ERROR", e.message, null)
                        }
                    }
                    else -> result.notImplemented()
                }
            }
    }

    // Let Flutter-side explicitly control when to enter PiP (navigation only)
    override fun onUserLeaveHint() {
        super.onUserLeaveHint()
    }

    override fun onPictureInPictureModeChanged(
        isInPictureInPictureMode: Boolean,
        newConfig: Configuration?
    ) {
        super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
        // Persist PiP state so we can safely exit it on resume
        val prefs = getSharedPreferences(PREFS, Context.MODE_PRIVATE)
        prefs.edit().putBoolean(KEY_WAS_IN_PIP, isInPictureInPictureMode).apply()
    }

    override fun onResume() {
        super.onResume()
        // When user brings app back, force full-screen (no PiP)
        ensureExitPip()
    }

    private fun ensureExitPip() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return

        val prefs = getSharedPreferences(PREFS, Context.MODE_PRIVATE)
        val wasInPip = prefs.getBoolean(KEY_WAS_IN_PIP, false)

        // Clear the persisted flag so we don't auto-re-enter PiP
        // Note: Android doesn't provide a direct API to exit PiP programmatically,
        // but when user opens app from launcher, it naturally returns to full-screen.
        // We just ensure we don't auto-re-enter PiP on resume.
        if (wasInPip) {
            prefs.edit().putBoolean(KEY_WAS_IN_PIP, false).apply()
        }
    }

    private fun checkActiveDeliveries(): Boolean {
        return try {
            val prefs: SharedPreferences = getSharedPreferences(
                "FlutterSharedPreferences",
                Context.MODE_PRIVATE
            )
            // Only check has_live_deliveries (verified by API)
            val hasLive = prefs.getBoolean("flutter.has_live_deliveries", false)
            hasLive
        } catch (e: Exception) {
            false
        }
    }
    
    private fun scheduleShiftEndAlarm(endTimeStr: String, startTimeStr: String) {
        try {
            Log.d("MainActivity", "📅 Scheduling shift end alarm - endTime: $endTimeStr, startTime: $startTimeStr")
            
            val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
            val intent = Intent(this, ShiftEndReceiver::class.java).apply {
                action = "com.nearle.partner.SHIFT_END_ALARM"
            }
            val pendingIntent = PendingIntent.getBroadcast(
                this,
                1001, // Unique request code
                intent,
                PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
            )
            
            // Parse end time (format: HH:mm:ss or HH:mm)
            val timeParts = endTimeStr.split(":")
            if (timeParts.size < 2) {
                Log.e("MainActivity", "❌ Invalid end time format: $endTimeStr")
                return
            }
            
            val endHour = timeParts[0].toIntOrNull() ?: 0
            val endMinute = timeParts[1].toIntOrNull() ?: 0
            
            val calendar = Calendar.getInstance().apply {
                set(Calendar.HOUR_OF_DAY, endHour)
                set(Calendar.MINUTE, endMinute)
                set(Calendar.SECOND, 0)
                set(Calendar.MILLISECOND, 0)
            }
            
            // Handle overnight shifts (if start > end)
            if (startTimeStr.isNotEmpty()) {
                val startParts = startTimeStr.split(":")
                if (startParts.size >= 2) {
                    val startHour = startParts[0].toIntOrNull() ?: 0
                    val startMinute = startParts[1].toIntOrNull() ?: 0
                    
                    if (startHour > endHour || (startHour == endHour && startMinute > endMinute)) {
                        // Overnight shift - if current time is before end time, schedule for tomorrow
                        val now = Calendar.getInstance()
                        if (now.before(calendar)) {
                            calendar.add(Calendar.DAY_OF_MONTH, 1)
                        }
                    }
                }
            }
            
            // ✅ CRITICAL: If shift end time has already passed today, trigger immediately
            val now = Calendar.getInstance()
            Log.d("MainActivity", "Current time: ${now.time}, Shift end time: ${calendar.time}")
            
            if (calendar.before(now) || calendar.equals(now)) {
                // Shift end time has passed - trigger break log immediately
                Log.d("MainActivity", "⚡ Shift end time ($endTimeStr) has already passed - triggering break log immediately")
                
                // Trigger the receiver immediately
                val immediateIntent = Intent(this, ShiftEndReceiver::class.java).apply {
                    action = "com.nearle.partner.SHIFT_END_ALARM"
                }
                sendBroadcast(immediateIntent)
                Log.d("MainActivity", "✅ Sent immediate broadcast to ShiftEndReceiver")
                
                // Also schedule for tomorrow to handle next shift
                calendar.add(Calendar.DAY_OF_MONTH, 1)
                Log.d("MainActivity", "📅 Also scheduled shift end alarm for tomorrow: ${calendar.time}")
            }
            
            // Schedule exact alarm (Android 12+ requires SCHEDULE_EXACT_ALARM permission)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                if (alarmManager.canScheduleExactAlarms()) {
                    alarmManager.setExactAndAllowWhileIdle(
                        AlarmManager.RTC_WAKEUP,
                        calendar.timeInMillis,
                        pendingIntent
                    )
                    Log.d("MainActivity", "✅ Scheduled exact shift end alarm for: ${calendar.time} (${calendar.timeInMillis})")
                } else {
                    // Fallback to inexact alarm
                    alarmManager.setAndAllowWhileIdle(
                        AlarmManager.RTC_WAKEUP,
                        calendar.timeInMillis,
                        pendingIntent
                    )
                    Log.w("MainActivity", "⚠️ Scheduled inexact shift end alarm (no permission) for: ${calendar.time}")
                }
            } else {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    alarmManager.setExactAndAllowWhileIdle(
                        AlarmManager.RTC_WAKEUP,
                        calendar.timeInMillis,
                        pendingIntent
                    )
                    Log.d("MainActivity", "✅ Scheduled exact shift end alarm (Android M+) for: ${calendar.time}")
                } else {
                    @Suppress("DEPRECATION")
                    alarmManager.setExact(
                        AlarmManager.RTC_WAKEUP,
                        calendar.timeInMillis,
                        pendingIntent
                    )
                    Log.d("MainActivity", "✅ Scheduled exact shift end alarm (legacy) for: ${calendar.time}")
                }
            }
        } catch (e: Exception) {
            Log.e("MainActivity", "❌ Error scheduling shift end alarm: ${e.message}", e)
            e.printStackTrace()
        }
    }
    
    private fun cancelShiftEndAlarm() {
        try {
            val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
            val intent = Intent(this, ShiftEndReceiver::class.java).apply {
                action = "com.nearle.partner.SHIFT_END_ALARM"
            }
            val pendingIntent = PendingIntent.getBroadcast(
                this,
                1001,
                intent,
                PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
            )
            alarmManager.cancel(pendingIntent)
            Log.d("MainActivity", "Cancelled shift end alarm")
        } catch (e: Exception) {
            Log.e("MainActivity", "Error cancelling shift end alarm: ${e.message}", e)
        }
    }
}

