package com.example.hmg_qline.hmg_qline

import android.app.AlarmManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import android.provider.Settings
import android.util.Log
import java.util.Calendar

/**
 * Utility class for scheduling app restart alarms.
 * Handles Android version-specific alarm scheduling with proper backward compatibility.
 *
 * Android Version Compatibility:
 * - Android 14+ (API 34): Uses USE_EXACT_ALARM or SCHEDULE_EXACT_ALARM with permission check
 * - Android 12-13 (API 31-33): Uses SCHEDULE_EXACT_ALARM with permission check
 * - Android 6-11 (API 23-30): Uses setExactAndAllowWhileIdle
 * - Android < 6 (API < 23): Uses setExact
 */
object AlarmScheduler {

    private const val TAG = "AlarmScheduler"
    private const val RESTART_ALARM_REQUEST_CODE = 1001

    /**
     * Schedule a daily restart alarm at the specified time.
     *
     * @param context Application context
     * @param hour Hour of day (0-23), default is 0 (midnight)
     * @param minute Minute (0-59), default is 15
     */
    fun scheduleRestartAlarm(context: Context, hour: Int = 0, minute: Int = 15) {
        val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager

        val intent = Intent(context, RestartAlarmReceiver::class.java).apply {
            action = RestartAlarmReceiver.ACTION_SCHEDULED_RESTART
        }

        val pendingIntent = PendingIntent.getBroadcast(
            context,
            RESTART_ALARM_REQUEST_CODE,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

        // Calculate next alarm time
        val calendar = Calendar.getInstance().apply {
            set(Calendar.HOUR_OF_DAY, hour)
            set(Calendar.MINUTE, minute)
            set(Calendar.SECOND, 0)
            set(Calendar.MILLISECOND, 0)

            // If the time has already passed today, schedule for tomorrow
            if (timeInMillis <= System.currentTimeMillis()) {
                add(Calendar.DAY_OF_YEAR, 1)
            }
        }

        // Cancel any existing alarm first
        alarmManager.cancel(pendingIntent)

        Log.d(TAG, "Scheduling restart alarm for: ${calendar.time}")
        Log.d(TAG, "Android SDK Version: ${Build.VERSION.SDK_INT}")

        // Schedule based on Android version
        when {
            // Android 14+ (API 34+)
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE -> {
                scheduleForAndroid14Plus(context, alarmManager, pendingIntent, calendar.timeInMillis)
            }
            // Android 12-13 (API 31-33)
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
                scheduleForAndroid12To13(context, alarmManager, pendingIntent, calendar.timeInMillis)
            }
            // Android 6-11 (API 23-30)
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> {
                alarmManager.setExactAndAllowWhileIdle(
                    AlarmManager.RTC_WAKEUP,
                    calendar.timeInMillis,
                    pendingIntent
                )
                Log.d(TAG, "Alarm scheduled using setExactAndAllowWhileIdle (API 23-30)")
            }
            // Android < 6 (API < 23)
            else -> {
                alarmManager.setExact(
                    AlarmManager.RTC_WAKEUP,
                    calendar.timeInMillis,
                    pendingIntent
                )
                Log.d(TAG, "Alarm scheduled using setExact (API < 23)")
            }
        }
    }

    /**
     * Schedule alarm for Android 14+ (API 34+)
     * Android 14 requires special handling for exact alarms.
     */
    private fun scheduleForAndroid14Plus(
        context: Context,
        alarmManager: AlarmManager,
        pendingIntent: PendingIntent,
        triggerTime: Long
    ) {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                if (alarmManager.canScheduleExactAlarms()) {
                    alarmManager.setExactAndAllowWhileIdle(
                        AlarmManager.RTC_WAKEUP,
                        triggerTime,
                        pendingIntent
                    )
                    Log.d(TAG, "Alarm scheduled using setExactAndAllowWhileIdle (API 34+)")
                } else {
                    // Fallback to inexact alarm if permission not granted
                    alarmManager.setAndAllowWhileIdle(
                        AlarmManager.RTC_WAKEUP,
                        triggerTime,
                        pendingIntent
                    )
                    Log.w(TAG, "Exact alarm permission not granted, using setAndAllowWhileIdle (API 34+)")
                }
            }
        } catch (e: SecurityException) {
            Log.e(TAG, "SecurityException scheduling alarm: ${e.message}")
            // Fallback to inexact alarm
            alarmManager.setAndAllowWhileIdle(
                AlarmManager.RTC_WAKEUP,
                triggerTime,
                pendingIntent
            )
        }
    }

    /**
     * Schedule alarm for Android 12-13 (API 31-33)
     */
    private fun scheduleForAndroid12To13(
        context: Context,
        alarmManager: AlarmManager,
        pendingIntent: PendingIntent,
        triggerTime: Long
    ) {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                if (alarmManager.canScheduleExactAlarms()) {
                    alarmManager.setExactAndAllowWhileIdle(
                        AlarmManager.RTC_WAKEUP,
                        triggerTime,
                        pendingIntent
                    )
                    Log.d(TAG, "Alarm scheduled using setExactAndAllowWhileIdle (API 31-33)")
                } else {
                    alarmManager.setAndAllowWhileIdle(
                        AlarmManager.RTC_WAKEUP,
                        triggerTime,
                        pendingIntent
                    )
                    Log.w(TAG, "Exact alarm permission not granted, using setAndAllowWhileIdle (API 31-33)")
                }
            }
        } catch (e: SecurityException) {
            Log.e(TAG, "SecurityException scheduling alarm: ${e.message}")
            alarmManager.setAndAllowWhileIdle(
                AlarmManager.RTC_WAKEUP,
                triggerTime,
                pendingIntent
            )
        }
    }

    /**
     * Cancel the scheduled restart alarm.
     */
    fun cancelRestartAlarm(context: Context) {
        val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager

        val intent = Intent(context, RestartAlarmReceiver::class.java).apply {
            action = RestartAlarmReceiver.ACTION_SCHEDULED_RESTART
        }

        val pendingIntent = PendingIntent.getBroadcast(
            context,
            RESTART_ALARM_REQUEST_CODE,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

        alarmManager.cancel(pendingIntent)
        Log.d(TAG, "Restart alarm cancelled")
    }

    /**
     * Check if the app can schedule exact alarms.
     * Returns true for Android < 12 (always allowed) or if permission is granted on Android 12+.
     */
    fun canScheduleExactAlarms(context: Context): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
            alarmManager.canScheduleExactAlarms()
        } else {
            true // Always allowed on older versions
        }
    }

    /**
     * Open system settings to request exact alarm permission (Android 12+).
     */
    fun requestExactAlarmPermission(context: Context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            try {
                val intent = Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM).apply {
                    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                }
                context.startActivity(intent)
            } catch (e: Exception) {
                Log.e(TAG, "Error opening exact alarm settings: ${e.message}")
            }
        }
    }
}

