/**
 * Upload utility with CSRF support for the Custom PHP Framework
 */
export class UploadManager {
    constructor(baseUrl = '') {
        this.baseUrl = baseUrl;
        this.csrfCache = new Map();
    }

    /**
     * Get CSRF tokens for a form
     * @param {string} action - Form action URL
     * @param {string} method - Form method (default: 'post')
     * @returns {Promise<{form_id: string, token: string, headers: Object}>}
     */
    async getCsrfTokens(action = '/', method = 'post') {
        const cacheKey = `${action}:${method}`;

        if (this.csrfCache.has(cacheKey)) {
            return this.csrfCache.get(cacheKey);
        }

        try {
            const response = await fetch(`${this.baseUrl}/api/csrf/token?action=${encodeURIComponent(action)}&method=${encodeURIComponent(method)}`, {
                method: 'GET',
                headers: {
                    'Accept': 'application/json',
                    'User-Agent': navigator.userAgent
                }
            });

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

            const tokens = await response.json();

            // Cache tokens for reuse
            this.csrfCache.set(cacheKey, tokens);

            return tokens;
        } catch (error) {
            console.error('Failed to get CSRF tokens:', error);
            throw error;
        }
    }

    /**
     * Upload an image file with CSRF protection
     * @param {File} file - The image file to upload
     * @param {Object} options - Upload options
     * @param {string} options.altText - Alt text for the image
     * @param {Function} options.onProgress - Progress callback
     * @param {AbortSignal} options.signal - Abort signal for cancellation
     * @returns {Promise<Object>} - Upload result
     */
    async uploadImage(file, options = {}) {
        const { altText = '', onProgress, signal } = options;

        try {
            // Get CSRF tokens
            const csrfTokens = await this.getCsrfTokens('/api/images', 'post');

            // Note: Honeypot validation is disabled for API routes
            // API routes use CSRF tokens for protection instead

            // Validate file
            if (!file || !(file instanceof File)) {
                throw new Error('Invalid file provided');
            }

            if (!file.type.startsWith('image/')) {
                throw new Error('File must be an image');
            }

            // Create FormData
            const formData = new FormData();
            formData.append('image', file);
            if (altText) {
                formData.append('alt_text', altText);
            }

            // Note: No honeypot fields needed for API routes
            // API routes are protected by CSRF tokens in headers

            // Create upload request
            const xhr = new XMLHttpRequest();

            return new Promise((resolve, reject) => {
                // Handle progress
                if (onProgress) {
                    xhr.upload.addEventListener('progress', (event) => {
                        if (event.lengthComputable) {
                            const percentComplete = (event.loaded / event.total) * 100;
                            onProgress(percentComplete, event.loaded, event.total);
                        }
                    });
                }

                // Handle completion
                xhr.addEventListener('load', () => {
                    if (xhr.status >= 200 && xhr.status < 300) {
                        try {
                            const result = JSON.parse(xhr.responseText);
                            resolve(result);
                        } catch (parseError) {
                            reject(new Error('Invalid JSON response'));
                        }
                    } else {
                        try {
                            const errorData = JSON.parse(xhr.responseText);
                            reject(new Error(errorData.message || `Upload failed with status ${xhr.status}`));
                        } catch {
                            reject(new Error(`Upload failed with status ${xhr.status}`));
                        }
                    }
                });

                // Handle errors
                xhr.addEventListener('error', () => {
                    reject(new Error('Network error during upload'));
                });

                xhr.addEventListener('abort', () => {
                    reject(new Error('Upload was cancelled'));
                });

                // Handle cancellation
                if (signal) {
                    signal.addEventListener('abort', () => {
                        xhr.abort();
                    });
                }

                // Open and send request
                xhr.open('POST', `${this.baseUrl}/api/images`);

                // Set CSRF headers
                xhr.setRequestHeader('X-CSRF-Form-ID', csrfTokens.form_id);
                xhr.setRequestHeader('X-CSRF-Token', csrfTokens.token);
                xhr.setRequestHeader('Accept', 'application/json');
                xhr.setRequestHeader('User-Agent', navigator.userAgent);

                xhr.send(formData);
            });

        } catch (error) {
            console.error('Upload failed:', error);
            throw error;
        }
    }

    /**
     * Upload multiple images with progress tracking
     * @param {File[]} files - Array of image files
     * @param {Object} options - Upload options
     * @returns {Promise<Object[]>} - Array of upload results
     */
    async uploadMultipleImages(files, options = {}) {
        const { onProgress, onFileComplete, signal } = options;
        const results = [];
        let completedCount = 0;

        for (const [index, file] of files.entries()) {
            try {
                const fileOptions = {
                    ...options,
                    onProgress: (percent, loaded, total) => {
                        if (onProgress) {
                            const overallProgress = ((completedCount + (percent / 100)) / files.length) * 100;
                            onProgress(overallProgress, index, files.length);
                        }
                    },
                    signal
                };

                const result = await this.uploadImage(file, fileOptions);
                results.push({ success: true, file: file.name, data: result });

                completedCount++;

                if (onFileComplete) {
                    onFileComplete(result, index, files.length);
                }

            } catch (error) {
                results.push({ success: false, file: file.name, error: error.message });
                completedCount++;
            }
        }

        return results;
    }

    /**
     * Clear CSRF token cache
     */
    clearCsrfCache() {
        this.csrfCache.clear();
    }
}

/**
 * File validation utilities
 */
export class FileValidator {
    static MAX_FILE_SIZE = 10 * 1024 * 1024; // 10MB
    static ALLOWED_TYPES = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'];

    static validateImage(file) {
        const errors = [];

        if (!file || !(file instanceof File)) {
            errors.push('Invalid file');
            return errors;
        }

        // Check file size
        if (file.size > this.MAX_FILE_SIZE) {
            errors.push(`File size must be less than ${this.MAX_FILE_SIZE / (1024 * 1024)}MB`);
        }

        // Check file type
        if (!this.ALLOWED_TYPES.includes(file.type)) {
            errors.push(`File type ${file.type} is not allowed. Allowed types: ${this.ALLOWED_TYPES.join(', ')}`);
        }

        // Check file name
        if (file.name.length > 255) {
            errors.push('File name is too long (max 255 characters)');
        }

        return errors;
    }

    static isValidImage(file) {
        return this.validateImage(file).length === 0;
    }
}

// Export a default instance
export default new UploadManager();