/**
 * AJAX Helper for AbsensiKu Application
 * This file contains helper functions for making AJAX requests to the API
 */

class AjaxHelper {
    constructor() {
        this.baseUrl = '/api';
        this.token = localStorage.getItem('auth_token');
        this.setupDefaults();
    }

    setupDefaults() {
        // Setup CSRF token and default headers
        $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
                'Authorization': this.token ? `Bearer ${this.token}` : '',
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            }
        });
    }

    updateToken(token) {
        this.token = token;
        localStorage.setItem('auth_token', token);
        this.setupDefaults();
    }

    clearToken() {
        this.token = null;
        localStorage.removeItem('auth_token');
        localStorage.removeItem('user_data');
    }

    // Generic AJAX request method
    async request(method, endpoint, data = null, options = {}) {
        const config = {
            url: `${this.baseUrl}${endpoint}`,
            type: method,
            ...options
        };

        if (data) {
            if (method === 'GET') {
                config.data = data;
            } else {
                config.data = JSON.stringify(data);
            }
        }

        try {
            const response = await $.ajax(config);
            return { success: true, data: response };
        } catch (xhr) {
            const error = xhr.responseJSON || { message: 'Network error occurred' };

            // Handle unauthorized access
            if (xhr.status === 401) {
                this.clearToken();
                window.location.href = '/login';
                return;
            }

            return {
                success: false,
                error: error,
                status: xhr.status
            };
        }
    }

    // Convenience methods
    async get(endpoint, params = null) {
        return this.request('GET', endpoint, params);
    }

    async post(endpoint, data) {
        return this.request('POST', endpoint, data);
    }

    async put(endpoint, data) {
        return this.request('PUT', endpoint, data);
    }

    async delete(endpoint) {
        return this.request('DELETE', endpoint);
    }

    // File upload method
    async uploadFile(endpoint, formData) {
        const config = {
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
                'Authorization': this.token ? `Bearer ${this.token}` : '',
            },
            processData: false,
            contentType: false
        };

        return this.request('POST', endpoint, formData, config);
    }

    // Authentication methods
    async login(credentials) {
        const result = await this.request('POST', '/login', credentials);
        if (result.success && result.data.data?.token) {
            this.updateToken(result.data.data.token);
            localStorage.setItem('user_data', JSON.stringify(result.data.data));
        }
        return result;
    }

    async logout() {
        const result = await this.request('POST', '/logout');
        this.clearToken();
        return result;
    }

    async getProfile() {
        return this.get('/profile');
    }

    // Admin API methods
    async getUsers(params = {}) {
        return this.get('/admin/users', params);
    }

    async createUser(userData) {
        return this.post('/admin/users', userData);
    }

    async updateUser(id, userData) {
        return this.put(`/admin/users/${id}`, userData);
    }

    async deleteUser(id) {
        return this.delete(`/admin/users/${id}`);
    }

    async getAttendances(params = {}) {
        return this.get('/admin/attendances', params);
    }

    async approveAttendance(id) {
        return this.put(`/admin/attendances/${id}/approve`);
    }

    async getPermissions(params = {}) {
        return this.get('/admin/permissions', params);
    }

    async approvePermission(id) {
        return this.put(`/admin/permissions/${id}/approve`);
    }

    async getLocations(params = {}) {
        return this.get('/admin/locations', params);
    }

    async createLocation(locationData) {
        return this.post('/admin/locations', locationData);
    }

    async updateLocation(id, locationData) {
        return this.put(`/admin/locations/${id}`, locationData);
    }

    async deleteLocation(id) {
        return this.delete(`/admin/locations/${id}`);
    }

    async getAttendanceReport(params = {}) {
        return this.get('/admin/reports/attendance', params);
    }

    async getPermissionReport(params = {}) {
        return this.get('/admin/reports/permission', params);
    }

    async getDashboardStats() {
        return this.get('/admin/reports/dashboard');
    }

    // Employee API methods
    async submitAttendance(attendanceData) {
        return this.post('/employee/attendance', attendanceData);
    }

    async getAttendanceHistory(params = {}) {
        return this.get('/employee/attendance/history', params);
    }

    async getTodayAttendanceStatus() {
        return this.get('/employee/attendance/today-status');
    }

    async submitPermission(permissionData) {
        return this.post('/employee/permission', permissionData);
    }

    async getPermissionHistory(params = {}) {
        return this.get('/employee/permission/history', params);
    }

    async cancelPermission(id) {
        return this.put(`/employee/permission/${id}/cancel`);
    }

    async updateProfile(profileData) {
        return this.put('/employee/profile', profileData);
    }

    async changePassword(passwordData) {
        return this.put('/employee/password', passwordData);
    }

    async uploadProfilePhoto(formData) {
        return this.uploadFile('/employee/profile/photo', formData);
    }
}

// Utility functions for UI interactions
class UIHelper {
    static showAlert(container, type, message, autoHide = true) {
        const alertHtml = `
            <div class="alert alert-${type} alert-dismissible fade show" role="alert">
                ${message}
                <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
            </div>
        `;

        $(container).html(alertHtml);

        if (autoHide) {
            setTimeout(() => {
                $('.alert').fadeOut('slow');
            }, 5000);
        }
    }

    static showValidationErrors(errors, formSelector = '') {
        Object.keys(errors).forEach(field => {
            const input = $(`${formSelector} [name="${field}"]`);
            const errorContainer = input.siblings('.invalid-feedback');

            input.addClass('is-invalid');
            errorContainer.text(errors[field][0]).show();
        });
    }

    static clearErrors(formSelector = '') {
        $(`${formSelector} .form-control`).removeClass('is-invalid');
        $(`${formSelector} .invalid-feedback`).hide().text('');
    }

    static setButtonLoading(button, loading = true, loadingText = 'Loading...') {
        const btn = $(button);
        const spinner = btn.find('.spinner-border');
        const btnText = btn.find('.btn-text');

        if (loading) {
            btn.prop('disabled', true);
            spinner.removeClass('d-none');
            btnText.text(loadingText);
        } else {
            btn.prop('disabled', false);
            spinner.addClass('d-none');
            btnText.text(btn.data('original-text') || 'Submit');
        }
    }

    static formatDate(dateString) {
        return new Date(dateString).toLocaleDateString('id-ID', {
            year: 'numeric',
            month: 'long',
            day: 'numeric'
        });
    }

    static formatDateTime(dateString) {
        return new Date(dateString).toLocaleString('id-ID', {
            year: 'numeric',
            month: 'long',
            day: 'numeric',
            hour: '2-digit',
            minute: '2-digit'
        });
    }
}

// Initialize global instances
const api = new AjaxHelper();
const ui = UIHelper;

// Check authentication on page load
$(document).ready(function() {
    const token = localStorage.getItem('auth_token');
    const currentPath = window.location.pathname;

    // Redirect to login if no token and not already on login page
    if (!token && currentPath !== '/login') {
        window.location.href = '/login';
    }

    // Redirect to dashboard if token exists and on login page
    if (token && currentPath === '/login') {
        window.location.href = '/dashboard';
    }
});
