package com.nearle.partner

import android.app.AlarmManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.PowerManager
import android.util.Log
import java.io.OutputStreamWriter
import java.net.HttpURLConnection
import java.net.URL
import java.text.SimpleDateFormat
import java.util.*

/**
 * BroadcastReceiver that triggers when shift end alarm fires
 * This works even when app is killed
 * 
 * When app is killed, we directly call the API to create break log
 * since we can't reliably start Flutter engine
 */
class ShiftEndReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        Log.d("ShiftEndReceiver", "🔔 Shift end alarm triggered at ${java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss", java.util.Locale.US).format(java.util.Calendar.getInstance().time)}")
        
        // ✅ CRITICAL: Acquire WakeLock to keep device awake during API call
        val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
        val wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ShiftEndReceiver::WakeLock")
        wakeLock.acquire(60 * 1000L) // Hold for 60 seconds max
        
        // Execute API call in background thread
        Thread {
            try {
                // Check if rider is still on duty
                val prefs: SharedPreferences = context.getSharedPreferences(
                    "FlutterSharedPreferences",
                    Context.MODE_PRIVATE
                )
                
                // ✅ Try multiple key formats (Flutter SharedPreferences uses "flutter." prefix)
                val onduty = prefs.getInt("flutter.onduty", 0)
                Log.d("ShiftEndReceiver", "Checking onduty: $onduty")
                
                if (onduty != 1) {
                    Log.d("ShiftEndReceiver", "Rider already offline (onduty=$onduty), skipping break log creation")
                    return@Thread
                }
                
                // Get required IDs - try both flutter.userid and flutter.userId
                val userid = prefs.getInt("flutter.userid", 0).takeIf { it != 0 } 
                    ?: prefs.getInt("flutter.userId", 0)
                val partnerid = prefs.getInt("flutter.partnerid", 0).takeIf { it != 0 }
                    ?: prefs.getInt("flutter.partnerId", 0)
                val shiftid = prefs.getInt("flutter.shiftid", 0).takeIf { it != 0 }
                    ?: prefs.getInt("flutter.shiftId", 0)
                val logid = prefs.getInt("flutter.logid", 0).takeIf { it != 0 }
                    ?: prefs.getInt("flutter.logId", 0)
                
                Log.d("ShiftEndReceiver", "Retrieved IDs: userid=$userid, partnerid=$partnerid, shiftid=$shiftid, logid=$logid")
                
                if (userid == 0) {
                    Log.e("ShiftEndReceiver", "❌ Missing userid, cannot create break log. Available keys: ${prefs.all.keys}")
                    return@Thread
                }
                
                // Get API base URL (check if live or dev)
                // ✅ Match homepage logic: use createbreaklog (not createbreakriderlog)
                val mainRoute = prefs.getString("flutter.mainRoute", "dev") ?: "dev"
                val isLive = mainRoute == "live"
                Log.d("ShiftEndReceiver", "API Route: $mainRoute (isLive=$isLive)")
                val baseUrl = if (isLive) {
                    "https://jupiter.nearle.app/live/api/v2/partners/createbreaklog"
                } else {
                    "https://jupiter.nearle.app/dev/api/v2/partners/createbreaklog"
                }
                
                // Create break log payload
                val now = Calendar.getInstance()
                val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US)
                val timeFormat = SimpleDateFormat("HH:mm:ss", Locale.US)
                val breakdate = dateFormat.format(now.time)
                val breakstart = timeFormat.format(now.time)
                val localBreakId = (System.currentTimeMillis() % 900).toInt() + 100
                
                // ✅ Compact JSON (no extra whitespace) - matches Flutter format
                val payload = """{"breakid":$localBreakId,"logid":$logid,"breakdate":"$breakdate","userid":$userid,"partnerid":$partnerid,"shiftid":$shiftid,"breakstart":"$breakstart","breakend":"","breakhours":0.0,"latitude":"0","longitude":"0"}"""
                
                Log.d("ShiftEndReceiver", "📤 Sending break log request to: $baseUrl")
                Log.d("ShiftEndReceiver", "📦 Payload: $payload")
                
                // Make API call
                val url = URL(baseUrl)
                val connection = url.openConnection() as HttpURLConnection
                connection.requestMethod = "POST"
                connection.setRequestProperty("Content-Type", "application/json")
                connection.setRequestProperty("Accept", "application/json")
                connection.doOutput = true
                connection.doInput = true
                connection.useCaches = false
                connection.connectTimeout = 15000 // Increased timeout
                connection.readTimeout = 15000
                
                Log.d("ShiftEndReceiver", "🔌 Connecting to API...")
                
                // Write payload
                val outputStream = connection.outputStream
                val writer = OutputStreamWriter(outputStream, "UTF-8")
                writer.write(payload)
                writer.flush()
                writer.close()
                
                Log.d("ShiftEndReceiver", "📨 Request sent, waiting for response...")
                
                val responseCode = connection.responseCode
                Log.d("ShiftEndReceiver", "📥 Break log API response: HTTP $responseCode")
                
                // Read response body for debugging
                try {
                    val responseStream = if (responseCode in 200..299) {
                        connection.inputStream
                    } else {
                        connection.errorStream
                    }
                    if (responseStream != null) {
                        val responseBody = responseStream.bufferedReader().use { it.readText() }
                        Log.d("ShiftEndReceiver", "📄 Response body: $responseBody")
                    }
                } catch (e: Exception) {
                    Log.w("ShiftEndReceiver", "Could not read response body: ${e.message}")
                }
                
                if (responseCode in 200..299) {
                    Log.d("ShiftEndReceiver", "✅ Break log created successfully (HTTP $responseCode)")
                    
                    // Set offline locally
                    prefs.edit()
                        .putInt("flutter.onduty", 0)
                        .putBoolean("flutter.online", false)
                        .apply()
                    
                    // Also update rider log to set onduty=0
                    val updateUrl = if (isLive) {
                        "https://jupiter.nearle.app/live/api/v2/partners/updateriderlog"
                    } else {
                        "https://jupiter.nearle.app/dev/api/v2/partners/updateriderlog"
                    }
                    
                    // ✅ Compact JSON (no extra whitespace)
                    val updatePayload = """{"userid":$userid,"onduty":0,"latitude":"0","longitude":"0"}"""
                    
                    Log.d("ShiftEndReceiver", "📤 Updating rider status to offline")
                    
                    try {
                        val updateConnection = URL(updateUrl).openConnection() as HttpURLConnection
                        updateConnection.requestMethod = "POST"
                        updateConnection.setRequestProperty("Content-Type", "application/json")
                        updateConnection.doOutput = true
                        updateConnection.connectTimeout = 5000
                        updateConnection.readTimeout = 5000
                        
                        val updateWriter = OutputStreamWriter(updateConnection.outputStream, "UTF-8")
                        updateWriter.write(updatePayload)
                        updateWriter.flush()
                        updateWriter.close()
                        
                        if (updateConnection.responseCode in 200..299) {
                            Log.d("ShiftEndReceiver", "✅ Rider status updated to Offline")
                        }
                        updateConnection.disconnect()
                    } catch (e: Exception) {
                        Log.e("ShiftEndReceiver", "Error updating rider status: ${e.message}")
                    }
                } else {
                    // Read error response for debugging
                    try {
                        val errorStream = connection.errorStream
                        if (errorStream != null) {
                            val errorResponse = errorStream.bufferedReader().use { it.readText() }
                            Log.e("ShiftEndReceiver", "❌ Failed to create break log: HTTP $responseCode\nError: $errorResponse")
                        } else {
                            Log.e("ShiftEndReceiver", "❌ Failed to create break log: HTTP $responseCode")
                        }
                    } catch (e: Exception) {
                        Log.e("ShiftEndReceiver", "❌ Failed to create break log: HTTP $responseCode (Error reading response: ${e.message})")
                    }
                }
                
                connection.disconnect()
                
                // ✅ CRITICAL: Reschedule alarm for tomorrow (so it works every day automatically)
                // This ensures the alarm fires every day at shift end time even if app is killed
                try {
                    val endTimeStr = prefs.getString("flutter.endtime", "") ?: ""
                    val startTimeStr = prefs.getString("flutter.starttime", "") ?: ""
                    Log.d("ShiftEndReceiver", "Rescheduling alarm - endTime: $endTimeStr, startTime: $startTimeStr")
                    
                    if (endTimeStr.isNotEmpty()) {
                        // Schedule alarm for tomorrow at the same time
                        val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
                        val intent = Intent(context, ShiftEndReceiver::class.java).apply {
                            action = "com.nearle.partner.SHIFT_END_ALARM"
                        }
                        val pendingIntent = PendingIntent.getBroadcast(
                            context,
                            1001,
                            intent,
                            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
                        )
                        
                        val timeParts = endTimeStr.split(":")
                        if (timeParts.size >= 2) {
                            val endHour = timeParts[0].toIntOrNull() ?: 0
                            val endMinute = timeParts[1].toIntOrNull() ?: 0
                            
                            val calendar = Calendar.getInstance().apply {
                                add(Calendar.DAY_OF_MONTH, 1) // Tomorrow
                                set(Calendar.HOUR_OF_DAY, endHour)
                                set(Calendar.MINUTE, endMinute)
                                set(Calendar.SECOND, 0)
                                set(Calendar.MILLISECOND, 0)
                            }
                            
                            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
                                if (alarmManager.canScheduleExactAlarms()) {
                                    alarmManager.setExactAndAllowWhileIdle(
                                        AlarmManager.RTC_WAKEUP,
                                        calendar.timeInMillis,
                                        pendingIntent
                                    )
                                    Log.d("ShiftEndReceiver", "✅ Rescheduled alarm for tomorrow: ${calendar.time}")
                                } else {
                                    alarmManager.setAndAllowWhileIdle(
                                        AlarmManager.RTC_WAKEUP,
                                        calendar.timeInMillis,
                                        pendingIntent
                                    )
                                }
                            } else {
                                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
                                    alarmManager.setExactAndAllowWhileIdle(
                                        AlarmManager.RTC_WAKEUP,
                                        calendar.timeInMillis,
                                        pendingIntent
                                    )
                                } else {
                                    @Suppress("DEPRECATION")
                                    alarmManager.setExact(
                                        AlarmManager.RTC_WAKEUP,
                                        calendar.timeInMillis,
                                        pendingIntent
                                    )
                                }
                                Log.d("ShiftEndReceiver", "✅ Rescheduled alarm for tomorrow: ${calendar.time}")
                            }
                        }
                    }
                } catch (e: Exception) {
                    Log.e("ShiftEndReceiver", "Error rescheduling alarm: ${e.message}", e)
                }
            } catch (e: Exception) {
                Log.e("ShiftEndReceiver", "❌ Error handling shift end: ${e.message}", e)
                e.printStackTrace()
            } finally {
                // ✅ CRITICAL: Release WakeLock in finally block
                try {
                    if (wakeLock.isHeld) {
                        wakeLock.release()
                        Log.d("ShiftEndReceiver", "🔓 WakeLock released")
                    }
                } catch (e: Exception) {
                    Log.e("ShiftEndReceiver", "Error releasing WakeLock: ${e.message}")
                }
            }
        }.start()
    }
}
