// Сервис кэширования данных для offline режима
type CachedRequest = {
  id: string;
  method: string;
  url: string;
  body?: unknown;
  timestamp: number;
  retries: number;
};

const CACHE_KEY = 'mkd_offline_cache';
const MAX_RETRIES = 10;
const MAX_CACHE_AGE = 7 * 24 * 60 * 60 * 1000; // 7 дней

class OfflineCacheService {
  // Сохранить запрос в кэш
  cacheRequest(method: string, url: string, body?: unknown): string {
    const cachedRequests = this.getCachedRequests();
    const id = `req-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
    
    const request: CachedRequest = {
      id,
      method,
      url,
      body,
      timestamp: Date.now(),
      retries: 0,
    };

    cachedRequests.push(request);
    this.saveCachedRequests(cachedRequests);
    
    return id;
  }

  // Получить все закэшированные запросы
  getCachedRequests(): CachedRequest[] {
    try {
      const stored = localStorage.getItem(CACHE_KEY);
      if (stored) {
        const requests = JSON.parse(stored) as CachedRequest[];
        // Фильтруем устаревшие запросы
        const now = Date.now();
        return requests.filter(req => now - req.timestamp < MAX_CACHE_AGE);
      }
      return [];
    } catch (e) {
      console.error('Failed to get cached requests', e);
      return [];
    }
  }

  // Сохранить закэшированные запросы
  private saveCachedRequests(requests: CachedRequest[]) {
    try {
      localStorage.setItem(CACHE_KEY, JSON.stringify(requests));
    } catch (e) {
      console.error('Failed to save cached requests', e);
    }
  }

  // Удалить запрос из кэша
  removeRequest(id: string): void {
    const cachedRequests = this.getCachedRequests();
    const filtered = cachedRequests.filter(req => req.id !== id);
    this.saveCachedRequests(filtered);
  }

  // Увеличить счётчик попыток для запроса
  incrementRetries(id: string): void {
    const cachedRequests = this.getCachedRequests();
    const updated = cachedRequests.map(req => {
      if (req.id === id) {
        return { ...req, retries: req.retries + 1 };
      }
      return req;
    });
    this.saveCachedRequests(updated);
  }

  // Синхронизировать все закэшированные запросы
  async syncCachedRequests(apiBaseUrl: string): Promise<{ success: number; failed: number }> {
    const cachedRequests = this.getCachedRequests();
    let success = 0;
    let failed = 0;

    for (const request of cachedRequests) {
      // Пропускаем запросы с превышенным лимитом попыток
      if (request.retries >= MAX_RETRIES) {
        this.removeRequest(request.id);
        failed++;
        continue;
      }

      try {
        const fullUrl = request.url.startsWith('http') 
          ? request.url 
          : `${apiBaseUrl}${request.url}`;

        const options: RequestInit = {
          method: request.method,
          headers: {
            'Content-Type': 'application/json',
          },
        };

        if (request.body && (request.method === 'POST' || request.method === 'PUT')) {
          options.body = JSON.stringify(request.body);
        }

        const response = await fetch(fullUrl, options);

        if (response.ok) {
          this.removeRequest(request.id);
          success++;
        } else {
          this.incrementRetries(request.id);
          failed++;
        }
      } catch (error) {
        this.incrementRetries(request.id);
        failed++;
      }
    }

    return { success, failed };
  }

  // Очистить весь кэш
  clearCache(): void {
    localStorage.removeItem(CACHE_KEY);
  }

  // Получить количество закэшированных запросов
  getCacheSize(): number {
    return this.getCachedRequests().length;
  }
}

// Создаём единственный экземпляр сервиса
export const offlineCacheService = new OfflineCacheService();
