package org.timesafari.dailynotification

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.util.Log
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

/**
 * Boot recovery receiver to reschedule notifications after device reboot
 * Implements RECEIVE_BOOT_COMPLETED functionality
 * 
 * @author Matthew Raymer
 * @version 1.1.0
 */
class BootReceiver : BroadcastReceiver() {
    
    companion object {
        private const val TAG = "DNP-BOOT"
    }

    override fun onReceive(context: Context, intent: Intent?) {
        when (intent?.action) {
            Intent.ACTION_BOOT_COMPLETED,
            Intent.ACTION_LOCKED_BOOT_COMPLETED -> {
                Log.i(TAG, "Boot completed, setting boot flag and starting recovery")
                
                // Phase 2: Set boot flag for scenario detection
                // This allows ReactivationManager to detect boot scenario on next app launch
                // Only set flag for actual boot events, not MY_PACKAGE_REPLACED
                val prefs = context.getSharedPreferences("dailynotification_recovery", Context.MODE_PRIVATE)
                prefs.edit().putLong("last_boot_at", System.currentTimeMillis()).apply()
                
                // Phase 3: Use ReactivationManager for boot recovery
                ReactivationManager.runBootRecovery(context)
            }
            Intent.ACTION_MY_PACKAGE_REPLACED -> {
                // App was updated - don't set boot flag, just run recovery
                // This prevents false BOOT detection when app is reinstalled during testing
                Log.i(TAG, "Package replaced, running recovery without setting boot flag")
                ReactivationManager.runBootRecovery(context)
            }
            else -> {
                Log.d(TAG, "Unhandled intent action: ${intent?.action}")
            }
        }
    }
    
    private suspend fun rescheduleNotifications(context: Context) {
        val db = DailyNotificationDatabase.getDatabase(context)
        val enabledSchedules = db.scheduleDao().getEnabled()
        
        Log.i(TAG, "Found ${enabledSchedules.size} enabled schedules to reschedule")
        
        enabledSchedules.forEach { schedule ->
            try {
                when (schedule.kind) {
                    "fetch" -> {
                        // Reschedule WorkManager fetch
                        val config = ContentFetchConfig(
                            enabled = schedule.enabled,
                            schedule = schedule.cron ?: schedule.clockTime ?: "0 9 * * *",
                            url = null, // Will use mock content
                            timeout = 30000,
                            retryAttempts = 3,
                            retryDelay = 1000,
                            callbacks = CallbackConfig()
                        )
                        FetchWorker.scheduleFetch(context, config)
                        Log.i(TAG, "Rescheduled fetch for schedule: ${schedule.id}")
                    }
                    "notify" -> {
                        // Reschedule AlarmManager notification
                        val nextRunTime = calculateNextRunTime(schedule)
                        if (nextRunTime > System.currentTimeMillis()) {
                            val (title, body) = ReactivationManager.getTitleBodyForSchedule(db, schedule)
                                ?: Pair("Daily Notification", "Your daily update is ready")
                            val config = UserNotificationConfig(
                                enabled = schedule.enabled,
                                schedule = schedule.cron ?: schedule.clockTime ?: "0 9 * * *",
                                title = title,
                                body = body,
                                sound = true,
                                vibration = true,
                                priority = "normal"
                            )
                            NotifyReceiver.scheduleExactNotification(
                                context,
                                nextRunTime,
                                config,
                                scheduleId = schedule.id,
                                source = ScheduleSource.BOOT_RECOVERY,
                                skipPendingIntentIdempotence = true
                            )
                            Log.i(TAG, "Rescheduled notification for schedule: ${schedule.id}")
                        }
                    }
                    else -> {
                        Log.w(TAG, "Unknown schedule kind: ${schedule.kind}")
                    }
                }
            } catch (e: Exception) {
                Log.e(TAG, "Failed to reschedule ${schedule.kind} for ${schedule.id}", e)
            }
        }
        
        // Record boot recovery in history
        try {
            db.historyDao().insert(
                History(
                    refId = "boot_recovery_${System.currentTimeMillis()}",
                    kind = "boot_recovery",
                    occurredAt = System.currentTimeMillis(),
                    outcome = "success",
                    diagJson = "{\"schedules_rescheduled\": ${enabledSchedules.size}}"
                )
            )
        } catch (e: Exception) {
            Log.e(TAG, "Failed to record boot recovery", e)
        }
    }
    
    private fun calculateNextRunTime(schedule: Schedule): Long {
        val now = System.currentTimeMillis()
        
        // Simple implementation - for production, use proper cron parsing
        return when {
            schedule.cron != null -> {
                // Parse cron expression and calculate next run
                // For now, return next day at 9 AM
                now + (24 * 60 * 60 * 1000L)
            }
            schedule.clockTime != null -> {
                // Parse HH:mm and calculate next run
                // For now, return next day at specified time
                now + (24 * 60 * 60 * 1000L)
            }
            else -> {
                // Default to next day at 9 AM
                now + (24 * 60 * 60 * 1000L)
            }
        }
    }
}

/**
 * Data classes for configuration (simplified versions)
 */
data class ContentFetchConfig(
    val enabled: Boolean,
    val schedule: String,
    val url: String? = null,
    val timeout: Int? = null,
    val retryAttempts: Int? = null,
    val retryDelay: Int? = null,
    val callbacks: CallbackConfig
)

data class UserNotificationConfig(
    val enabled: Boolean,
    val schedule: String,
    val title: String? = null,
    val body: String? = null,
    val sound: Boolean? = null,
    val vibration: Boolean? = null,
    val priority: String? = null
)

data class CallbackConfig(
    val apiService: String? = null,
    val database: String? = null,
    val reporting: String? = null
)
