// ====== API Communication ======

import { API_ENDPOINTS, APP_CONFIG, ERROR_MESSAGES } from '../config/constants.js';
import { authManager } from './auth.js';
import { showNotification } from './helpers.js';

class ApiClient {
    constructor() {
        this.baseURL = APP_CONFIG.BASE_URL;
        this.timeout = APP_CONFIG.API_TIMEOUT;
    }

    async request(endpoint, options = {}) {
        const url = `${this.baseURL}${endpoint}`;
        const controller = new AbortController();
        const timeoutId = setTimeout(() => controller.abort(), this.timeout);

        const config = {
            headers: {
                'Content-Type': 'application/json',
                ...options.headers
            },
            signal: controller.signal,
            ...options
        };

        // Add auth token if available
        if (authManager.isAuthenticated()) {
            config.headers['Authorization'] = `Bearer ${authManager.token}`;
        }

        try {
            const response = await fetch(url, config);
            clearTimeout(timeoutId);

            // Handle non-JSON responses
            const contentType = response.headers.get('content-type');
            const data = contentType && contentType.includes('application/json') 
                ? await response.json() 
                : await response.text();

            if (!response.ok) {
                throw new Error(data.message || ERROR_MESSAGES.SERVER_ERROR);
            }

            return data;

        } catch (error) {
            clearTimeout(timeoutId);
            
            if (error.name === 'AbortError') {
                throw new Error('Request timeout');
            }

            if (error.name === 'TypeError') {
                throw new Error(ERROR_MESSAGES.NETWORK_ERROR);
            }

            throw error;
        }
    }

    // HTTP method shortcuts
    async get(endpoint, options = {}) {
        return this.request(endpoint, { ...options, method: 'GET' });
    }

    async post(endpoint, data = {}, options = {}) {
        return this.request(endpoint, {
            ...options,
            method: 'POST',
            body: JSON.stringify(data)
        });
    }

    async put(endpoint, data = {}, options = {}) {
        return this.request(endpoint, {
            ...options,
            method: 'PUT',
            body: JSON.stringify(data)
        });
    }

    async patch(endpoint, data = {}, options = {}) {
        return this.request(endpoint, {
            ...options,
            method: 'PATCH',
            body: JSON.stringify(data)
        });
    }

    async delete(endpoint, options = {}) {
        return this.request(endpoint, { ...options, method: 'DELETE' });
    }

    // File upload
    async upload(endpoint, formData, onProgress = null) {
        const url = `${this.baseURL}${endpoint}`;
        
        return new Promise((resolve, reject) => {
            const xhr = new XMLHttpRequest();
            
            // Progress tracking
            if (onProgress) {
                xhr.upload.addEventListener('progress', (e) => {
                    if (e.lengthComputable) {
                        onProgress((e.loaded / e.total) * 100);
                    }
                });
            }
            
            xhr.addEventListener('load', () => {
                if (xhr.status >= 200 && xhr.status < 300) {
                    try {
                        resolve(JSON.parse(xhr.responseText));
                    } catch {
                        resolve(xhr.responseText);
                    }
                } else {
                    reject(new Error(xhr.statusText));
                }
            });
            
            xhr.addEventListener('error', () => reject(new Error(ERROR_MESSAGES.NETWORK_ERROR)));
            xhr.addEventListener('abort', () => reject(new Error('Upload cancelled')));
            
            xhr.open('POST', url);
            
            // Add auth header
            if (authManager.isAuthenticated()) {
                xhr.setRequestHeader('Authorization', `Bearer ${authManager.token}`);
            }
            
            xhr.send(formData);
        });
    }
}

// Create singleton instance
export const apiClient = new ApiClient();