package com.atridad.ascently.widget

import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.widget.RemoteViews
import com.atridad.ascently.MainActivity
import com.atridad.ascently.R
import com.atridad.ascently.data.database.AscentlyDatabase
import com.atridad.ascently.data.repository.ClimbRepository
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import java.time.LocalDate

class ClimbStatsWidgetProvider : AppWidgetProvider() {

    private val job = SupervisorJob()
    private val coroutineScope = CoroutineScope(Dispatchers.IO + job)

    override fun onUpdate(
        context: Context,
        appWidgetManager: AppWidgetManager,
        appWidgetIds: IntArray,
    ) {
        for (appWidgetId in appWidgetIds) {
            updateAppWidget(context, appWidgetManager, appWidgetId)
        }
    }

    override fun onEnabled(context: Context) {}

    override fun onDisabled(context: Context) {
        job.cancel()
    }

    private fun updateAppWidget(
        context: Context,
        appWidgetManager: AppWidgetManager,
        appWidgetId: Int,
    ) {
        coroutineScope.launch {
            try {
                val database = AscentlyDatabase.getDatabase(context)
                val repository = ClimbRepository(database, context)

                // Get last 7 days date range (rolling period)
                val today = LocalDate.now()
                val sevenDaysAgo = today.minusDays(6) // Today + 6 days ago = 7 days total

                // Fetch all sessions and attempts
                val sessions = repository.getAllSessions().first()
                val attempts = repository.getAllAttempts().first()

                // Filter for last 7 days across all gyms
                val weekSessions =
                    sessions.filter { session ->
                        try {
                            val sessionDate = LocalDate.parse(session.date.substring(0, 10))
                            !sessionDate.isBefore(sevenDaysAgo) && !sessionDate.isAfter(today)
                        } catch (_: Exception) {
                            false
                        }
                    }

                val weekSessionIds = weekSessions.map { it.id }.toSet()

                // Count total attempts this week
                val totalAttempts =
                    attempts.count { attempt -> weekSessionIds.contains(attempt.sessionId) }

                // Count sessions this week
                val totalSessions = weekSessions.size

                launch(Dispatchers.Main) {
                    val views = RemoteViews(context.packageName, R.layout.widget_climb_stats)

                    // Set weekly stats
                    views.setTextViewText(R.id.widget_attempts_value, totalAttempts.toString())
                    views.setTextViewText(R.id.widget_sessions_value, totalSessions.toString())

                    val intent =
                        Intent(context, MainActivity::class.java).apply {
                            flags =
                                Intent.FLAG_ACTIVITY_NEW_TASK or
                                Intent.FLAG_ACTIVITY_CLEAR_TOP
                        }
                    val pendingIntent =
                        PendingIntent.getActivity(
                            context,
                            0,
                            intent,
                            PendingIntent.FLAG_UPDATE_CURRENT or
                                PendingIntent.FLAG_IMMUTABLE,
                        )
                    views.setOnClickPendingIntent(R.id.widget_container, pendingIntent)

                    appWidgetManager.updateAppWidget(appWidgetId, views)
                }
            } catch (_: Exception) {
                launch(Dispatchers.Main) {
                    val views = RemoteViews(context.packageName, R.layout.widget_climb_stats)
                    views.setTextViewText(R.id.widget_attempts_value, "0")
                    views.setTextViewText(R.id.widget_sessions_value, "0")

                    val intent = Intent(context, MainActivity::class.java)
                    val pendingIntent =
                        PendingIntent.getActivity(
                            context,
                            0,
                            intent,
                            PendingIntent.FLAG_UPDATE_CURRENT or
                                PendingIntent.FLAG_IMMUTABLE,
                        )
                    views.setOnClickPendingIntent(R.id.widget_container, pendingIntent)

                    appWidgetManager.updateAppWidget(appWidgetId, views)
                }
            }
        }
    }

    companion object {
        fun updateAllWidgets(context: Context) {
            val appWidgetManager = AppWidgetManager.getInstance(context)
            val componentName = ComponentName(context, ClimbStatsWidgetProvider::class.java)
            val appWidgetIds = appWidgetManager.getAppWidgetIds(componentName)

            val intent =
                Intent(context, ClimbStatsWidgetProvider::class.java).apply {
                    action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
                    putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds)
                }
            context.sendBroadcast(intent)
        }
    }
}
