/**
 * TimeSafari Native Fetcher Implementation (Android/Kotlin)
 * 
 * Example implementation of NativeNotificationContentFetcher for Android.
 * This runs in background workers and does NOT require JavaScript bridge.
 * 
 * @author Matthew Raymer
 * @version 1.0.0
 */

package org.timesafari.notification

import org.timesafari.dailynotification.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

/**
 * TimeSafari native content fetcher
 * 
 * Implements the NativeNotificationContentFetcher SPI to provide
 * TimeSafari-specific notification content fetching for background workers.
 */
class TimeSafariNativeFetcher(
    private val api: TimeSafariApi,
    private val tokenProvider: TokenProvider,
    private val starredPlanIds: List<String>
) : NativeNotificationContentFetcher {

    override suspend fun fetchContent(context: FetchContext): List<NotificationContent> {
        return withContext(Dispatchers.IO) {
            try {
                // 1. Get fresh authentication token
                val jwt = tokenProvider.freshToken()
                
                // 2. Fetch TimeSafari data in parallel
                val offersToPerson = async { api.fetchOffersToPerson(jwt) }
                val offersToPlans = async { api.fetchOffersToPlans(jwt) }
                val projectUpdates = async {
                    if (starredPlanIds.isNotEmpty()) {
                        api.fetchProjectsLastUpdated(starredPlanIds, jwt)
                    } else {
                        null
                    }
                }
                
                // Wait for all requests
                val offersPersonResult = offersToPerson.await()
                val offersPlansResult = offersToPlans.await()
                val updatesResult = projectUpdates.await()
                
                // 3. Convert to NotificationContent list
                buildList {
                    // Add offers to person
                    offersPersonResult?.data?.forEach { offer ->
                        add(
                            NotificationContent(
                                id = "offer_person_${offer.id}",
                                title = "New Offer: ${offer.title}",
                                body = offer.description ?: "",
                                scheduledTime = context.scheduledTime 
                                    ?: (System.currentTimeMillis() + 3_600_000),
                                fetchTime = context.fetchTime,
                                mediaUrl = offer.imageUrl,
                                ttlSeconds = 86_400, // 24 hours
                                dedupeKey = "offer_person_${offer.id}_${offer.updatedAt}",
                                priority = "default",
                                metadata = mapOf(
                                    "offerId" to offer.id,
                                    "issuerDid" to offer.issuerDid,
                                    "source" to "offers_to_person"
                                )
                            )
                        )
                    }
                    
                    // Add offers to plans
                    offersPlansResult?.data?.forEach { offer ->
                        add(
                            NotificationContent(
                                id = "offer_plan_${offer.id}",
                                title = "Offer for Your Project: ${offer.projectName}",
                                body = offer.description ?: "",
                                scheduledTime = context.scheduledTime 
                                    ?: (System.currentTimeMillis() + 3_600_000),
                                fetchTime = context.fetchTime,
                                mediaUrl = offer.imageUrl,
                                ttlSeconds = 86_400,
                                dedupeKey = "offer_plan_${offer.id}_${offer.updatedAt}",
                                priority = "default",
                                metadata = mapOf(
                                    "offerId" to offer.id,
                                    "planHandleId" to offer.planHandleId,
                                    "source" to "offers_to_plans"
                                )
                            )
                        )
                    }
                    
                    // Add project updates
                    updatesResult?.data?.forEach { update ->
                        add(
                            NotificationContent(
                                id = "project_${update.planSummary.jwtId}",
                                title = "${update.planSummary.name} Updated",
                                body = "New updates for ${update.planSummary.name}",
                                scheduledTime = context.scheduledTime 
                                    ?: (System.currentTimeMillis() + 3_600_000),
                                fetchTime = context.fetchTime,
                                mediaUrl = update.planSummary.image,
                                ttlSeconds = 86_400,
                                dedupeKey = "project_${update.planSummary.handleId}_${update.planSummary.jwtId}",
                                priority = "default",
                                metadata = mapOf(
                                    "planHandleId" to update.planSummary.handleId,
                                    "jwtId" to update.planSummary.jwtId,
                                    "source" to "project_updates"
                                )
                            )
                        )
                    }
                }
            } catch (e: Exception) {
                // Log error and return empty list
                // Plugin will handle retry based on SchedulingPolicy
                android.util.Log.e("TimeSafariFetcher", "Fetch failed", e)
                emptyList()
            }
        }
    }
}

/**
 * Registration in Application.onCreate()
 */
class TimeSafariApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        
        // Register native fetcher
        val api = TimeSafariApiClient(context = this)
        val tokenProvider = JWTokenProvider(activeDid = getActiveDid())
        val starredPlanIds = getStarredPlanIds()
        
        val fetcher = TimeSafariNativeFetcher(
            api = api,
            tokenProvider = tokenProvider,
            starredPlanIds = starredPlanIds
        )
        
        DailyNotification.setNativeFetcher(fetcher)
    }
}

