package com.safecheckin.app.service

import android.app.Notification
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.content.pm.ServiceInfo
import android.os.Build
import android.os.IBinder
import androidx.core.app.NotificationCompat
import com.safecheckin.app.MainActivity
import com.safecheckin.app.R
import com.safecheckin.app.SafeCheckInApp
import com.safecheckin.app.data.model.CheckInRecord
import com.safecheckin.app.data.repository.Repository
import com.safecheckin.app.utils.NotificationHelper
import kotlinx.coroutines.*
import java.util.Calendar

/**
 * 前台服务 - 保持通知常驻，显示存活状态和倒计时
 */
class CheckInNotificationService : Service() {

    companion object {
        const val ACTION_START = "com.safecheckin.app.action.START_SERVICE"
        const val ACTION_STOP = "com.safecheckin.app.action.STOP_SERVICE"
        const val ACTION_CHECK_IN = "com.safecheckin.app.action.CHECK_IN"
        const val ACTION_TEST_NOTIFICATION = "com.safecheckin.app.action.TEST_NOTIFICATION"
        const val FOREGROUND_NOTIFICATION_ID = 100
        
        private var serviceScope: CoroutineScope? = null
        private var lastReminderTime: Long = 0L
        private const val REMINDER_INTERVAL_MS = 2 * 60 * 60 * 1000L // 2 hours
        
        fun start(context: Context) {
            val intent = Intent(context, CheckInNotificationService::class.java).apply {
                action = ACTION_START
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(intent)
            } else {
                context.startService(intent)
            }
        }
        
        fun stop(context: Context) {
            val intent = Intent(context, CheckInNotificationService::class.java).apply {
                action = ACTION_STOP
            }
            context.startService(intent)
        }
        
        fun sendCheckInAction(context: Context) {
            val intent = Intent(context, CheckInNotificationService::class.java).apply {
                action = ACTION_CHECK_IN
            }
            context.startService(intent)
        }
        
        fun sendTestNotification(context: Context) {
            val intent = Intent(context, CheckInNotificationService::class.java).apply {
                action = ACTION_TEST_NOTIFICATION
            }
            context.startService(intent)
        }
    }

    private lateinit var repository: Repository
    
    override fun onCreate() {
        super.onCreate()
        repository = Repository(applicationContext)
    }
    
    override fun onBind(intent: Intent?): IBinder? = null
    
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        when (intent?.action) {
            ACTION_START -> startForegroundService()
            ACTION_STOP -> stopForegroundService()
            ACTION_CHECK_IN -> performCheckIn()
            ACTION_TEST_NOTIFICATION -> testNotification()
        }
        
        return START_STICKY
    }
    
    private fun startForegroundService() {
        // Create notification channels first
        NotificationHelper.createNotificationChannels(applicationContext)
        
        // Start as foreground service
        val notification = buildForegroundNotification(
            isCheckedIn = false,
            countdownText = "计算中...",
            consecutiveDays = 0
        )
        
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
            startForeground(
                FOREGROUND_NOTIFICATION_ID,
                notification,
                ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE
            )
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            startForeground(
                FOREGROUND_NOTIFICATION_ID,
                notification,
                ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
            )
        } else {
            startForeground(FOREGROUND_NOTIFICATION_ID, notification)
        }
        
        // Start periodic update job
        startUpdateJob()
    }
    
    private fun stopForegroundService() {
        serviceScope?.cancel()
        serviceScope = null
        stopForeground(STOP_FOREGROUND_REMOVE)
        stopSelf()
    }
    
    private fun performCheckIn() {
        serviceScope?.launch {
            val record = CheckInRecord(
                timestamp = System.currentTimeMillis(),
                isSuccess = true,
                note = "从通知打卡"
            )
            repository.insertCheckIn(record)
            NotificationHelper.showCheckInSuccessNotification(applicationContext)
        }
    }
    
    private fun testNotification() {
        NotificationHelper.showTestReminderNotification(applicationContext)
    }
    
    private fun startUpdateJob() {
        serviceScope?.cancel()
        serviceScope = CoroutineScope(Dispatchers.Main + SupervisorJob())
        
        serviceScope?.launch {
            while (isActive) {
                updateNotification()
                delay(60_000) // Update every minute
            }
        }
        
        // Start reminder job
        serviceScope?.launch {
            repository.allCheckIns.collect { checkIns ->
                val today = Calendar.getInstance().apply {
                    set(Calendar.HOUR_OF_DAY, 0)
                    set(Calendar.MINUTE, 0)
                    set(Calendar.SECOND, 0)
                    set(Calendar.MILLISECOND, 0)
                }.timeInMillis
                
                val todayCheckIn = checkIns.find { it.timestamp >= today }
                
                // If not checked in today and hasn't sent reminder in last 2 hours
                if (todayCheckIn == null) {
                    val now = System.currentTimeMillis()
                    if (now - lastReminderTime >= REMINDER_INTERVAL_MS) {
                        NotificationHelper.showReminderNotification(applicationContext)
                        lastReminderTime = now
                    }
                }
            }
        }
    }
    
    private suspend fun updateNotification() {
        var checkIns: List<com.safecheckin.app.data.model.CheckInRecord> = emptyList()
        var gracePeriodHours: Int = 24
        
        repository.allCheckIns.collect { list ->
            checkIns = list
        }
        repository.gracePeriodHours.collect { hours ->
            gracePeriodHours = hours
        }
        
        val today = Calendar.getInstance().apply {
            set(Calendar.HOUR_OF_DAY, 0)
            set(Calendar.MINUTE, 0)
            set(Calendar.SECOND, 0)
            set(Calendar.MILLISECOND, 0)
        }.timeInMillis
        
        var todayCheckIn: com.safecheckin.app.data.model.CheckInRecord? = null
        for (checkIn in checkIns) {
            if (checkIn.timestamp >= today) {
                todayCheckIn = checkIn
                break
            }
        }
        val isCheckedIn = todayCheckIn != null
        
        // Calculate consecutive days
        val consecutiveDays = calculateConsecutiveDays(checkIns)
        
        // Calculate countdown to warning
        val gracePeriodMs = gracePeriodHours.toLong() * 60 * 60 * 1000L
        
        var lastCheckInTime = today
        var maxTimestamp = 0L
        for (checkIn in checkIns) {
            if (checkIn.timestamp > maxTimestamp) {
                maxTimestamp = checkIn.timestamp
                lastCheckInTime = checkIn.timestamp
            }
        }
        
        val warningTime = lastCheckInTime + gracePeriodMs
        val remainingMs = warningTime - System.currentTimeMillis()
        
        val countdownText = if (remainingMs > 0) {
            val hours = (remainingMs / (60 * 60 * 1000)).toInt()
            val minutes = ((remainingMs % (60 * 60 * 1000)) / (60 * 1000)).toInt()
            if (isCheckedIn) {
                "距离下次预警: ${hours}小时${minutes}分钟"
            } else {
                "⚠️ 今日未打卡，距离预警: ${hours}小时${minutes}分钟"
            }
        } else {
            "⚠️ 已超时！请立即打卡"
        }
        
        // Update notification
        val notificationManager = getSystemService(NotificationManager::class.java)
        val notification = buildForegroundNotification(
            isCheckedIn = isCheckedIn,
            countdownText = countdownText,
            consecutiveDays = consecutiveDays
        )
        notificationManager.notify(FOREGROUND_NOTIFICATION_ID, notification)
    }
    
    private fun calculateConsecutiveDays(checkIns: List<com.safecheckin.app.data.model.CheckInRecord>): Int {
        if (checkIns.isEmpty()) return 0
        
        val sortedDates = checkIns.map { 
            Calendar.getInstance().apply { timeInMillis = it.timestamp }.apply {
                set(Calendar.HOUR_OF_DAY, 0)
                set(Calendar.MINUTE, 0)
                set(Calendar.SECOND, 0)
                set(Calendar.MILLISECOND, 0)
            }.timeInMillis
        }.distinct().sortedDescending()
        
        var consecutiveDays = 1
        val today = Calendar.getInstance().apply {
            set(Calendar.HOUR_OF_DAY, 0)
            set(Calendar.MINUTE, 0)
            set(Calendar.SECOND, 0)
            set(Calendar.MILLISECOND, 0)
        }.timeInMillis
        
        // Check if checked in today
        val firstDate = sortedDates.firstOrNull()
        if (firstDate != today) {
            // Check if checked in yesterday
            val yesterday = today - 24L * 60 * 60 * 1000
            if (firstDate != yesterday) {
                return 0
            }
        }
        
        for (i in 1 until sortedDates.size) {
            val prevDay = sortedDates[i - 1] - 24L * 60 * 60 * 1000
            if (sortedDates[i] == prevDay) {
                consecutiveDays++
            } else {
                break
            }
        }
        
        return consecutiveDays
    }
    
    private fun buildForegroundNotification(
        isCheckedIn: Boolean,
        countdownText: String,
        consecutiveDays: Int
    ): Notification {
        // Open app intent
        val openIntent = Intent(this, MainActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
        }
        val openPendingIntent = PendingIntent.getActivity(
            this, 0, openIntent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )
        
        // Check-in action intent
        val checkInIntent = Intent(this, CheckInNotificationService::class.java).apply {
            action = ACTION_CHECK_IN
        }
        val checkInPendingIntent = PendingIntent.getService(
            this, 1, checkInIntent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )
        
        val statusText = if (isCheckedIn) {
            "✅ 今日已打卡 - 连续存活 $consecutiveDays 天"
        } else {
            "❌ 今日未打卡 - 连续存活 $consecutiveDays 天"
        }
        
        return NotificationCompat.Builder(this, SafeCheckInApp.STATUS_CHANNEL_ID)
            .setSmallIcon(android.R.drawable.ic_dialog_info)
            .setContentTitle(getString(R.string.app_name))
            .setContentText(statusText)
            .setSubText(countdownText)
            .setContentIntent(openPendingIntent)
            .setOngoing(true) // Cannot be dismissed
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .setCategory(NotificationCompat.CATEGORY_STATUS)
            .addAction(
                android.R.drawable.ic_menu_add,
                getString(R.string.notification_check_in_action),
                checkInPendingIntent
            )
            .setStyle(NotificationCompat.BigTextStyle().bigText("$statusText\n$countdownText"))
            .build()
    }
}