/**
 * SoftRefetchWorker.java
 * 
 * WorkManager worker for soft re-fetching notification content
 * Prefetches fresh content for tomorrow's notifications asynchronously
 * 
 * @author Matthew Raymer
 * @version 1.0.0
 */

package org.timesafari.dailynotification;

import android.content.Context;
import android.os.Trace;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.work.Worker;
import androidx.work.WorkerParameters;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * WorkManager worker for soft re-fetching notification content
 * 
 * This worker runs 2 hours before tomorrow's notifications to prefetch
 * fresh content, ensuring tomorrow's notifications are always fresh.
 */
public class SoftRefetchWorker extends Worker {
    
    private static final String TAG = "SoftRefetchWorker";
    
    public SoftRefetchWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }
    
    @NonNull
    @Override
    public Result doWork() {
        Trace.beginSection("DN:SoftRefetch");
        try {
            long tomorrowScheduledTime = getInputData().getLong("tomorrow_scheduled_time", -1);
            String action = getInputData().getString("action");
            String originalId = getInputData().getString("original_id");
            
            if (tomorrowScheduledTime == -1 || !"soft_refetch".equals(action)) {
                Log.e(TAG, "DN|SOFT_REFETCH_ERR invalid_input_data");
                return Result.failure();
            }
            
            Log.d(TAG, "DN|SOFT_REFETCH_START original_id=" + originalId + 
                      " tomorrow_time=" + tomorrowScheduledTime);
            
            // Check if we're within 2 hours of tomorrow's notification
            long currentTime = System.currentTimeMillis();
            long timeUntilNotification = tomorrowScheduledTime - currentTime;
            
            if (timeUntilNotification < 0) {
                Log.w(TAG, "DN|SOFT_REFETCH_SKIP notification_already_past");
                return Result.success();
            }
            
            if (timeUntilNotification > TimeUnit.HOURS.toMillis(2)) {
                Log.w(TAG, "DN|SOFT_REFETCH_SKIP too_early time_until=" + (timeUntilNotification / 1000 / 60) + "min");
                return Result.success();
            }
            
            // Fetch fresh content for tomorrow
            boolean refetchSuccess = performSoftRefetch(tomorrowScheduledTime, originalId);
            
            if (refetchSuccess) {
                Log.i(TAG, "DN|SOFT_REFETCH_OK original_id=" + originalId);
                return Result.success();
            } else {
                Log.e(TAG, "DN|SOFT_REFETCH_ERR original_id=" + originalId);
                return Result.retry();
            }
            
        } catch (Exception e) {
            Log.e(TAG, "DN|SOFT_REFETCH_ERR exception=" + e.getMessage(), e);
            return Result.retry();
        } finally {
            Trace.endSection();
        }
    }
    
    /**
     * Perform soft re-fetch for tomorrow's notification content
     * 
     * @param tomorrowScheduledTime The scheduled time for tomorrow's notification
     * @param originalId The original notification ID
     * @return true if refetch succeeded, false otherwise
     */
    private boolean performSoftRefetch(long tomorrowScheduledTime, String originalId) {
        try {
            // Get all notifications from storage
            DailyNotificationStorage storage = new DailyNotificationStorage(getApplicationContext());
            List<NotificationContent> notifications = storage.getAllNotifications();
            
            // Find tomorrow's notification (within 1 minute tolerance)
            long toleranceMs = 60 * 1000; // 1 minute tolerance
            NotificationContent tomorrowNotification = null;
            
            for (NotificationContent notification : notifications) {
                if (Math.abs(notification.getScheduledTime() - tomorrowScheduledTime) <= toleranceMs) {
                    tomorrowNotification = notification;
                    Log.d(TAG, "DN|SOFT_REFETCH_FOUND tomorrow_id=" + notification.getId());
                    break;
                }
            }
            
            if (tomorrowNotification == null) {
                Log.w(TAG, "DN|SOFT_REFETCH_ERR no_tomorrow_notification_found");
                return false;
            }
            
            // Fetch fresh content
            DailyNotificationFetcher fetcher = new DailyNotificationFetcher(
                getApplicationContext(), 
                storage
            );
            
            NotificationContent freshContent = fetcher.fetchContentImmediately();
            
            if (freshContent != null && freshContent.getTitle() != null && !freshContent.getTitle().isEmpty()) {
                Log.i(TAG, "DN|SOFT_REFETCH_FRESH_CONTENT tomorrow_id=" + tomorrowNotification.getId());
                
                // Update tomorrow's notification with fresh content
                tomorrowNotification.setTitle(freshContent.getTitle());
                tomorrowNotification.setBody(freshContent.getBody());
                tomorrowNotification.setSound(freshContent.isSound());
                tomorrowNotification.setPriority(freshContent.getPriority());
                tomorrowNotification.setUrl(freshContent.getUrl());
                tomorrowNotification.setMediaUrl(freshContent.getMediaUrl());
                // Keep original scheduled time and ID
                
                // Save updated content to storage
                storage.saveNotificationContent(tomorrowNotification);
                
                Log.i(TAG, "DN|SOFT_REFETCH_UPDATED tomorrow_id=" + tomorrowNotification.getId());
                return true;
            } else {
                Log.w(TAG, "DN|SOFT_REFETCH_FAIL no_fresh_content tomorrow_id=" + tomorrowNotification.getId());
                return false;
            }
            
        } catch (Exception e) {
            Log.e(TAG, "DN|SOFT_REFETCH_ERR exception=" + e.getMessage(), e);
            return false;
        }
    }
}
