/**
 * PLATAFORMA GANADERA — API Client
 * Consumo AJAX centralizado de la API REST
 */
const API = {
    baseUrl: (window.APP_BASE || '') + '/api',
    token: localStorage.getItem('ganadera_token') || null,

    /**
     * Configurar token
     */
    setToken(token) {
        this.token = token;
        if (token) {
            localStorage.setItem('ganadera_token', token);
        } else {
            localStorage.removeItem('ganadera_token');
        }
    },

    /**
     * Headers por defecto
     */
    getHeaders() {
        const headers = {
            'Content-Type': 'application/json',
            'X-Requested-With': 'XMLHttpRequest',
        };
        if (this.token) {
            headers['Authorization'] = `Bearer ${this.token}`;
        }
        return headers;
    },

    /**
     * Petición genérica
     */
    async request(method, endpoint, data = null, options = {}) {
        const url = `${this.baseUrl}${endpoint}`;
        const config = {
            method,
            headers: this.getHeaders(),
            ...options,
        };

        if (data && ['POST', 'PUT', 'PATCH', 'DELETE'].includes(method)) {
            // Si es FormData (para archivos), no setear Content-Type
            if (data instanceof FormData) {
                delete config.headers['Content-Type'];
                config.body = data;
            } else {
                config.body = JSON.stringify(data);
            }
        }

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

            // Token expirado
            if (response.status === 401) {
                this.setToken(null);
                if (!endpoint.includes('/auth/login')) {
                    window.location.href = (window.APP_BASE || '') + '/login';
                    return;
                }
            }

            const result = await response.json();
            return result;
        } catch (error) {
            // Modo offline — guardar para sync
            if (!navigator.onLine && ['POST', 'PUT'].includes(method)) {
                await this.savePendingRequest(method, url, data);
                return {
                    success: true,
                    offline: true,
                    message: 'Guardado localmente. Se sincronizará al tener conexión.',
                };
            }

            console.error(`API Error [${method} ${endpoint}]:`, error);
            return {
                success: false,
                error: 'Error de conexión',
            };
        }
    },

    // ─── Métodos HTTP ───────────────────────────────────────

    get(endpoint) { return this.request('GET', endpoint); },
    post(endpoint, data) { return this.request('POST', endpoint, data); },
    put(endpoint, data) { return this.request('PUT', endpoint, data); },
    delete(endpoint, data) { return this.request('DELETE', endpoint, data); },

    // ─── Upload de archivos ─────────────────────────────────

    async upload(endpoint, fileOrFormData, fieldName = 'photo', extraData = {}) {
        let fd;
        if (fileOrFormData instanceof FormData) {
            fd = fileOrFormData;
        } else {
            fd = new FormData();
            fd.append(fieldName, fileOrFormData);
        }
        // Append extra metadata fields
        Object.entries(extraData).forEach(([key, val]) => {
            if (val !== undefined && val !== null) fd.append(key, val);
        });
        return this.request('POST', endpoint, fd);
    },

    // ─── Auth ───────────────────────────────────────────────

    async login(username, password) {
        const result = await this.post('/auth/login', { username, password });
        if (result.success && result.data?.token) {
            this.setToken(result.data.token);
            // Guardar datos de usuario
            localStorage.setItem('ganadera_user', JSON.stringify(result.data.user));
            localStorage.setItem('ganadera_permissions', JSON.stringify(result.data.permissions));
            localStorage.setItem('ganadera_ranches', JSON.stringify(result.data.ranches));
        }
        return result;
    },

    async logout() {
        await this.post('/auth/logout');
        this.setToken(null);
        localStorage.removeItem('ganadera_user');
        localStorage.removeItem('ganadera_permissions');
        localStorage.removeItem('ganadera_ranches');
        window.location.href = (window.APP_BASE || '') + '/login';
    },

    getUser() {
        try {
            return JSON.parse(localStorage.getItem('ganadera_user'));
        } catch { return null; }
    },

    getPermissions() {
        try {
            return JSON.parse(localStorage.getItem('ganadera_permissions')) || [];
        } catch { return []; }
    },

    hasPermission(slug) {
        const perms = this.getPermissions();
        return perms.includes(slug) || this.getUser()?.role_slug === 'superadmin';
    },

    isAuthenticated() {
        return !!this.token && !!this.getUser();
    },

    // ─── Offline sync ───────────────────────────────────────

    async savePendingRequest(method, url, data) {
        try {
            const db = await this.openDB();
            const tx = db.transaction('pending', 'readwrite');
            const store = tx.objectStore('pending');
            await store.add({
                method,
                url,
                body: JSON.stringify(data),
                headers: this.getHeaders(),
                timestamp: Date.now(),
            });
        } catch (e) {
            console.error('Error saving pending request:', e);
        }
    },

    openDB() {
        return new Promise((resolve, reject) => {
            const request = indexedDB.open('ganadera-offline', 1);
            request.onupgradeneeded = (e) => {
                const db = e.target.result;
                if (!db.objectStoreNames.contains('pending')) {
                    db.createObjectStore('pending', { keyPath: 'id', autoIncrement: true });
                }
            };
            request.onsuccess = (e) => resolve(e.target.result);
            request.onerror = (e) => reject(e.target.error);
        });
    },
};

// ─── RANCH SELECTOR ─────────────────────────────────────────
const RanchManager = {
    getCurrentRanchId() {
        return localStorage.getItem('ganadera_current_ranch') || null;
    },

    setCurrentRanch(ranchId) {
        localStorage.setItem('ganadera_current_ranch', ranchId);
    },

    getRanches() {
        try {
            return JSON.parse(localStorage.getItem('ganadera_ranches')) || [];
        } catch { return []; }
    },
};
