// ====== Form Handling ======

import { debounce } from '../core/utils.js';
import { $, $$, setLoadingState, showNotification } from '../core/helpers.js';
import { validation } from './validation.js';
import { apiClient } from '../core/api.js';

class FormManager {
    constructor() {
        this.forms = new Map();
        this.init();
    }

    init() {
        this.setupGlobalFormHandlers();
    }

    setupGlobalFormHandlers() {
        // Auto-save for forms with data-auto-save attribute
        document.addEventListener('input', debounce((e) => {
            const form = e.target.closest('form[data-auto-save]');
            if (form) {
                this.autoSaveForm(form);
            }
        }, 1000));

        // Password visibility toggles
        document.addEventListener('click', (e) => {
            const toggle = e.target.closest('.password-toggle');
            if (toggle) {
                this.togglePasswordVisibility(toggle);
            }
        });
    }

    registerForm(form, options = {}) {
        const formId = form.id || `form-${Date.now()}`;
        
        this.forms.set(formId, {
            element: form,
            options: {
                autoValidate: true,
                showErrors: true,
                ...options
            }
        });

        this.setupFormEvents(form, options);
        return formId;
    }

    setupFormEvents(form, options) {
        // Real-time validation
        if (options.autoValidate) {
            form.addEventListener('input', debounce((e) => {
                this.validateField(e.target);
            }, 300));
        }

        // Form submission
        form.addEventListener('submit', async (e) => {
            e.preventDefault();
            await this.handleFormSubmit(form, options);
        });

        // Field focus for error clearing
        form.addEventListener('focusin', (e) => {
            if (e.target.classList.contains('error')) {
                this.clearFieldError(e.target);
            }
        });
    }

    async handleFormSubmit(form, options) {
        const submitButton = form.querySelector('button[type="submit"]');
        const isValid = await this.validateForm(form);

        if (!isValid) {
            showNotification('Please fix the errors before submitting.', 'error');
            return;
        }

        setLoadingState(submitButton, true);

        try {
            const formData = new FormData(form);
            const data = Object.fromEntries(formData.entries());

            if (options.onSubmit) {
                await options.onSubmit(data, form);
            } else {
                // Default form submission
                await this.submitForm(form, data);
            }

            if (options.onSuccess) {
                options.onSuccess(data, form);
            }

        } catch (error) {
            console.error('Form submission error:', error);
            
            if (options.onError) {
                options.onError(error, form);
            } else {
                showNotification(error.message || 'Form submission failed.', 'error');
            }
        } finally {
            setLoadingState(submitButton, false);
        }
    }

    async submitForm(form, data) {
        const method = form.method || 'POST';
        const action = form.action || window.location.href;

        const response = await apiClient.request(action, {
            method: method,
            body: data
        });

        showNotification('Form submitted successfully!', 'success');
        return response;
    }

    async validateForm(form) {
        const fields = $$('[data-validate]', form);
        let isValid = true;

        for (const field of fields) {
            const fieldValid = await this.validateField(field);
            if (!fieldValid) isValid = false;
        }

        return isValid;
    }

    async validateField(field) {
        const rules = field.getAttribute('data-validate');
        const value = field.value.trim();
        
        if (!rules) return true;

        const result = await validation.validateField(value, rules, field);
        
        if (result.isValid) {
            this.showFieldSuccess(field);
            return true;
        } else {
            this.showFieldError(field, result.errors);
            return false;
        }
    }

    showFieldError(field, errors) {
        this.clearFieldError(field);
        
        field.classList.add('error');
        
        const errorElement = document.createElement('div');
        errorElement.className = 'field-error';
        errorElement.textContent = errors[0]; // Show first error
        
        field.parentNode.appendChild(errorElement);
    }

    showFieldSuccess(field) {
        this.clearFieldError(field);
        field.classList.add('success');
    }

    clearFieldError(field) {
        field.classList.remove('error', 'success');
        
        const existingError = field.parentNode.querySelector('.field-error');
        if (existingError) {
            existingError.remove();
        }
    }

    togglePasswordVisibility(toggle) {
        const input = toggle.previousElementSibling;
        const isPassword = input.type === 'password';
        
        input.type = isPassword ? 'text' : 'password';
        toggle.textContent = isPassword ? '🙈' : '👁️';
    }

    async autoSaveForm(form) {
        const formData = new FormData(form);
        const data = Object.fromEntries(formData.entries());
        
        try {
            // Save to localStorage or send to auto-save endpoint
            const autoSaveKey = `autosave-${form.id}`;
            localStorage.setItem(autoSaveKey, JSON.stringify(data));
            
            // Show auto-save indicator
            this.showAutoSaveIndicator(form, true);
            
            setTimeout(() => {
                this.showAutoSaveIndicator(form, false);
            }, 2000);
            
        } catch (error) {
            console.warn('Auto-save failed:', error);
        }
    }

    showAutoSaveIndicator(form, saving) {
        let indicator = form.querySelector('.auto-save-indicator');
        
        if (!indicator) {
            indicator = document.createElement('div');
            indicator.className = 'auto-save-indicator';
            form.appendChild(indicator);
        }
        
        indicator.textContent = saving ? 'Saving...' : 'Saved';
        indicator.classList.toggle('saving', saving);
    }

    loadAutoSavedData(form) {
        const autoSaveKey = `autosave-${form.id}`;
        const savedData = localStorage.getItem(autoSaveKey);
        
        if (savedData) {
            const data = JSON.parse(savedData);
            this.populateForm(form, data);
            
            // Ask user if they want to restore saved data
            if (confirm('We found auto-saved data. Would you like to restore it?')) {
                this.populateForm(form, data);
            }
        }
    }

    populateForm(form, data) {
        Object.keys(data).forEach(key => {
            const field = form.querySelector(`[name="${key}"]`);
            if (field) {
                field.value = data[key];
            }
        });
    }

    clearForm(form) {
        form.reset();
        
        // Clear validation states
        $$('.error, .success', form).forEach(field => {
            field.classList.remove('error', 'success');
        });
        
        // Clear error messages
        $$('.field-error', form).forEach(error => error.remove());
        
        // Clear auto-saved data
        const autoSaveKey = `autosave-${form.id}`;
        localStorage.removeItem(autoSaveKey);
    }
}

// Create singleton instance
export const formManager = new FormManager();