/**
 * JavaScript Content Fetcher Implementation (TypeScript)
 * 
 * Example implementation of JsNotificationContentFetcher for foreground/manual refresh.
 * 
 * NOTE: This is used ONLY for foreground operations. Background workers use
 * the Native Fetcher SPI (Kotlin/Swift) for reliability.
 * 
 * @author Matthew Raymer
 * @version 1.0.0
 */

import { DailyNotification } from '@timesafari/daily-notification-plugin';
import type {
  JsNotificationContentFetcher,
  FetchContext,
  NotificationContent
} from '@timesafari/daily-notification-plugin';
import { TimeSafariAPI } from './timesafari-api'; // Host app's API client

/**
 * TimeSafari JavaScript content fetcher
 * 
 * Implements JsNotificationContentFetcher for foreground/manual refresh.
 * Background workers use the native Kotlin/Swift implementation.
 */
class TimeSafariJsFetcher implements JsNotificationContentFetcher {
  constructor(
    private api: TimeSafariAPI,
    private activeDid: string,
    private starredPlanIds: string[]
  ) {}

  async fetchContent(context: FetchContext): Promise<NotificationContent[]> {
    try {
      // 1. Generate JWT for authentication
      const jwt = await this.api.generateJWT(this.activeDid);

      // 2. Fetch TimeSafari data in parallel
      const [offersToPerson, offersToPlans, projectUpdates] = await Promise.all([
        this.api.fetchOffersToPerson(jwt),
        this.api.fetchOffersToPlans(jwt),
        this.starredPlanIds.length > 0
          ? this.api.fetchProjectsLastUpdated(this.starredPlanIds, jwt)
          : Promise.resolve(null)
      ]);

      // 3. Convert to NotificationContent array
      const contents: NotificationContent[] = [];

      // Convert offers to person
      if (offersToPerson?.data) {
        for (const offer of offersToPerson.data) {
          contents.push({
            id: `offer_person_${offer.id}`,
            title: `New Offer: ${offer.title}`,
            body: offer.description || '',
            scheduledTime: context.scheduledTime || Date.now() + 3600000,
            fetchTime: context.fetchTime,
            mediaUrl: offer.imageUrl,
            ttlSeconds: 86400, // 24 hours
            dedupeKey: `offer_person_${offer.id}_${offer.updatedAt}`,
            priority: 'default',
            metadata: {
              offerId: offer.id,
              issuerDid: offer.issuerDid,
              source: 'offers_to_person'
            }
          });
        }
      }

      // Convert offers to plans
      if (offersToPlans?.data) {
        for (const offer of offersToPlans.data) {
          contents.push({
            id: `offer_plan_${offer.id}`,
            title: `Offer for Your Project: ${offer.projectName}`,
            body: offer.description || '',
            scheduledTime: context.scheduledTime || Date.now() + 3600000,
            fetchTime: context.fetchTime,
            mediaUrl: offer.imageUrl,
            ttlSeconds: 86400,
            dedupeKey: `offer_plan_${offer.id}_${offer.updatedAt}`,
            priority: 'default',
            metadata: {
              offerId: offer.id,
              planHandleId: offer.planHandleId,
              source: 'offers_to_plans'
            }
          });
        }
      }

      // Convert project updates
      if (projectUpdates?.data) {
        for (const update of projectUpdates.data) {
          contents.push({
            id: `project_${update.planSummary.jwtId}`,
            title: `${update.planSummary.name} Updated`,
            body: `New updates for ${update.planSummary.name}`,
            scheduledTime: context.scheduledTime || Date.now() + 3600000,
            fetchTime: context.fetchTime,
            mediaUrl: update.planSummary.image,
            ttlSeconds: 86400,
            dedupeKey: `project_${update.planSummary.handleId}_${update.planSummary.jwtId}`,
            priority: 'default',
            metadata: {
              planHandleId: update.planSummary.handleId,
              jwtId: update.planSummary.jwtId,
              source: 'project_updates'
            }
          });
        }
      }

      return contents;
    } catch (error) {
      console.error('TimeSafari fetch failed:', error);
      // Return empty array - plugin will handle retry based on policy
      return [];
    }
  }
}

/**
 * Register fetcher and configure policy
 */
export async function setupDailyNotification(
  api: TimeSafariAPI,
  activeDid: string,
  starredPlanIds: string[]
): Promise<void> {
  // Create JS fetcher for foreground operations
  const jsFetcher = new TimeSafariJsFetcher(api, activeDid, starredPlanIds);
  DailyNotification.setJsContentFetcher(jsFetcher);

  // Configure scheduling policy
  await DailyNotification.setPolicy({
    prefetchWindowMs: 5 * 60 * 1000, // 5 minutes before scheduled time
    retryBackoff: {
      minMs: 2000,
      maxMs: 600000, // 10 minutes max
      factor: 2,
      jitterPct: 20
    },
    maxBatchSize: 50,
    dedupeHorizonMs: 24 * 60 * 60 * 1000, // 24 hours
    cacheTtlSeconds: 6 * 60 * 60, // 6 hours default
    exactAlarmsAllowed: true // If app has permission
  });

  // Enable native fetcher (required for background workers)
  await DailyNotification.enableNativeFetcher(true);
}

