// Feed Sync Service

import { fetchFeeds, fetchFeed } from './feed-service';
import { useFeedStore } from '@/stores/feed-store';
import { FeedSubscription, FeedItem } from '@/types/feed';
import {
  saveFeedItems,
  getAllFeedItems,
  getFeedItems as getFeedItemsFromDb,
  saveSubscription,
} from './database';

// Calculate next fetch time based on interval
function calculateNextFetchTime(intervalMinutes: number): Date {
  const now = new Date();
  now.setMinutes(now.getMinutes() + intervalMinutes);
  return now;
}

// Manual sync function for a single feed
export async function syncFeed(subscription: FeedSubscription): Promise<{ success: boolean; itemsSynced: number }> {
  const result = await fetchFeed(
    subscription.url,
    subscription.httpAuth
  );

  if (result.success && result.feed) {
    // Save feed items to database
    if (result.feed.items && result.feed.items.length > 0) {
      await saveFeedItems(subscription.id, result.feed.items);
    }

    // Update subscription in store and database
    const updates = {
      lastFetchedAt: new Date(),
      nextFetchAt: calculateNextFetchTime(subscription.fetchInterval),
      error: undefined,
      title: result.feed.title,
    };
    
    useFeedStore.getState().updateSubscription(subscription.id, updates);
    await saveSubscription({ ...subscription, ...updates });
    
    return { success: true, itemsSynced: result.feed.items?.length || 0 };
  } else {
    useFeedStore.getState().updateSubscription(subscription.id, {
      error: result.error || 'Unknown error',
    });
    return { success: false, itemsSynced: 0 };
  }
}

// Sync all enabled feeds
export async function syncAllFeeds(): Promise<{ success: boolean; totalItemsSynced: number }> {
  const subscriptions = useFeedStore
    .getState()
    .subscriptions.filter((sub) => sub.enabled);

  let totalItemsSynced = 0;
  let hasErrors = false;

  for (const subscription of subscriptions) {
    const result = await syncFeed(subscription);
    if (!result.success) {
      hasErrors = true;
    }
    totalItemsSynced += result.itemsSynced;
  }

  return { success: !hasErrors, totalItemsSynced };
}

// Get feeds that are due for sync
export function getFeedsDueForSync(): FeedSubscription[] {
  const now = new Date();
  return useFeedStore.getState().subscriptions.filter(
    (sub) => sub.enabled && new Date(sub.nextFetchAt || 0) <= now
  );
}

// Get feed items from local database (offline support)
export async function getLocalFeedItems(
  subscriptionId?: string,
  limit: number = 50,
  offset: number = 0
): Promise<FeedItem[]> {
  return getFeedItemsFromDb(subscriptionId, limit, offset);
}

// Get all feed items from local database
export async function getAllLocalFeedItems(limit: number = 100): Promise<FeedItem[]> {
  return getAllFeedItems(limit);
}

// Check if we have any local data
export async function hasLocalData(): Promise<boolean> {
  const items = await getAllFeedItems(1);
  return items.length > 0;
}

// Conflict resolution strategies
export type ConflictResolutionStrategy = 'newer' | 'older' | 'local' | 'remote';

interface ConflictResolutionOptions {
  strategy: ConflictResolutionStrategy;
  localItem: FeedItem;
  remoteItem: FeedItem;
}

export function resolveConflict(options: ConflictResolutionOptions): FeedItem {
  const { strategy, localItem, remoteItem } = options;

  switch (strategy) {
    case 'newer':
      const localDate = localItem.updated || localItem.published || new Date(0);
      const remoteDate = remoteItem.updated || remoteItem.published || new Date(0);
      return remoteDate > localDate ? remoteItem : localItem;
    
    case 'older':
      const olderLocalDate = localItem.updated || localItem.published || new Date();
      const olderRemoteDate = remoteItem.updated || remoteItem.published || new Date();
      return olderRemoteDate < olderLocalDate ? remoteItem : localItem;
    
    case 'local':
      return localItem;
    
    case 'remote':
      return remoteItem;
    
    default:
      return remoteItem;
  }
}
