/**
 * APIService - Centralized API communication service
 * Handles all HTTP requests to the backend server
 */

class APIService {
    constructor() {
        this._baseURL = window.location.origin;
        this._cache = new Map();
    }

    /**
     * Generic fetch wrapper with error handling
     * @private
     */
    async _fetch(endpoint, options = {}) {
        try {
            const url = `${this._baseURL}${endpoint}`;
            const response = await fetch(url, {
                headers: {
                    'Content-Type': 'application/json',
                    ...options.headers
                },
                ...options
            });

            if (!response.ok) {
                throw new Error(`API request failed: ${response.status} ${response.statusText}`);
            }

            return await response.json();
        } catch (error) {
            console.error(`❌ API Error [${endpoint}]:`, error);
            throw error;
        }
    }

    /**
     * Get all available books
     * @returns {Promise<Array>} - List of books
     */
    async getBooks() {
        const cacheKey = 'books';
        if (this._cache.has(cacheKey)) {
            return this._cache.get(cacheKey);
        }

        const books = await this._fetch('/api/books');
        this._cache.set(cacheKey, books);
        console.log(`📚 Loaded ${books.length} books from API`);
        return books;
    }

    /**
     * Get LLM configuration
     * @returns {Promise<Object>} - LLM config
     */
    async getLLMConfig() {
        return await this._fetch('/api/llm-config');
    }

    /**
     * Save progress data
     * @param {Object} progressData - Progress data to save
     * @returns {Promise<Object>} - Save response
     */
    async saveProgress(progressData) {
        return await this._fetch('/api/progress/save', {
            method: 'POST',
            body: JSON.stringify(progressData)
        });
    }

    /**
     * Merge progress data (for sync)
     * @param {Object} mergeData - Data to merge
     * @returns {Promise<Object>} - Merge response
     */
    async mergeProgress(mergeData) {
        return await this._fetch('/api/progress/merge', {
            method: 'POST',
            body: JSON.stringify(mergeData)
        });
    }

    /**
     * Get sync status
     * @returns {Promise<Object>} - Sync status
     */
    async getSyncStatus() {
        return await this._fetch('/api/progress/sync-status');
    }

    /**
     * Load DRS progress for a specific book/chapter
     * @param {string} bookId - Book ID
     * @param {string} chapterId - Chapter ID
     * @returns {Promise<Object>} - Progress data
     */
    async loadDRSProgress(bookId, chapterId) {
        return await this._fetch(`/api/progress/load/drs/${bookId}/${chapterId}`);
    }

    /**
     * Load flashcards progress
     * @returns {Promise<Object>} - Flashcards progress
     */
    async loadFlashcardsProgress() {
        return await this._fetch('/api/progress/load/flashcards');
    }

    /**
     * Load content from books or chapters directory
     * @param {string} contentId - Book or chapter ID
     * @param {string} type - 'book' or 'chapter'
     * @returns {Promise<Object>} - Content data
     */
    async loadContent(contentId, type = 'book') {
        const cacheKey = `${type}-${contentId}`;
        if (this._cache.has(cacheKey)) {
            return this._cache.get(cacheKey);
        }

        // Try loading from appropriate directory
        const directory = type === 'book' ? 'books' : 'chapters';
        const response = await fetch(`${this._baseURL}/content/${directory}/${contentId}.json`);

        if (!response.ok) {
            // Don't cache errors - let caller handle fallback
            throw new Error(`Failed to load ${type} content: ${response.status}`);
        }

        const content = await response.json();
        this._cache.set(cacheKey, content); // Only cache successful loads
        console.log(`📂 Loaded ${type} content: ${contentId}`);
        return content;
    }

    /**
     * Load book metadata
     * @param {string} bookId - Book ID
     * @returns {Promise<Object>} - Book data
     */
    async loadBook(bookId) {
        return await this.loadContent(bookId, 'book');
    }

    /**
     * Load chapter content
     * @param {string} chapterId - Chapter ID
     * @returns {Promise<Object>} - Chapter data
     */
    async loadChapter(chapterId) {
        return await this.loadContent(chapterId, 'chapter');
    }

    /**
     * Clear all cached data
     */
    clearCache() {
        this._cache.clear();
        console.log('🧹 API cache cleared');
    }

    /**
     * Clear specific cache entry
     * @param {string} key - Cache key to clear
     */
    clearCacheEntry(key) {
        this._cache.delete(key);
        console.log(`🧹 Cache entry cleared: ${key}`);
    }
}

// Create singleton instance
const apiService = new APIService();

// Export as ES6 module
export default apiService;
