/**
 * Admin Console - Utils
 * 工具函数（日期格式化、数据转换等）
 */

const Utils = {
    /**
     * 日期格式化
     * @param {Date|string|number} date - 日期对象、字符串或时间戳
     * @param {string} format - 格式模板，默认 'YYYY-MM-DD HH:mm:ss'
     * @returns {string} 格式化后的日期字符串
     */
    formatDate(date, format = 'YYYY-MM-DD HH:mm:ss') {
        if (!date) return '-';
        
        const d = new Date(date);
        if (isNaN(d.getTime())) return '-';
        
        const year = d.getFullYear();
        const month = String(d.getMonth() + 1).padStart(2, '0');
        const day = String(d.getDate()).padStart(2, '0');
        const hours = String(d.getHours()).padStart(2, '0');
        const minutes = String(d.getMinutes()).padStart(2, '0');
        const seconds = String(d.getSeconds()).padStart(2, '0');
        
        return format
            .replace('YYYY', year)
            .replace('MM', month)
            .replace('DD', day)
            .replace('HH', hours)
            .replace('mm', minutes)
            .replace('ss', seconds);
    },

    /**
     * 格式化日期（仅日期部分）
     * @param {Date|string|number} date
     * @returns {string}
     */
    formatDateOnly(date) {
        return this.formatDate(date, 'YYYY-MM-DD');
    },

    /**
     * 格式化金额
     * @param {number} amount - 金额
     * @param {number} decimals - 小数位数，默认 2
     * @returns {string}
     */
    formatAmount(amount, decimals = 2) {
        if (amount === null || amount === undefined) return '¥0.00';
        const num = parseFloat(amount);
        if (isNaN(num)) return '¥0.00';
        return '¥' + num.toFixed(decimals).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
    },

    /**
     * 格式化数字（千分位）
     * @param {number} num
     * @returns {string}
     */
    formatNumber(num) {
        if (num === null || num === undefined) return '0';
        const n = parseInt(num);
        if (isNaN(n)) return '0';
        return n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
    },

    /**
     * 获取日期范围
     * @param {string} range - 范围类型：today, yesterday, last7days, last30days
     * @returns {Object} { startDate, endDate }
     */
    getDateRange(range) {
        const today = new Date();
        today.setHours(0, 0, 0, 0);
        
        const format = (d) => this.formatDateOnly(d);
        
        switch (range) {
            case 'today':
                return { startDate: format(today), endDate: format(today) };
            case 'yesterday':
                const yesterday = new Date(today);
                yesterday.setDate(yesterday.getDate() - 1);
                return { startDate: format(yesterday), endDate: format(yesterday) };
            case 'last7days':
                const last7 = new Date(today);
                last7.setDate(last7.getDate() - 6);
                return { startDate: format(last7), endDate: format(today) };
            case 'last30days':
                const last30 = new Date(today);
                last30.setDate(last30.getDate() - 29);
                return { startDate: format(last30), endDate: format(today) };
            default:
                return { startDate: format(today), endDate: format(today) };
        }
    },

    /**
     * 判断日期范围是否不超过一年
     * @param {string} startDate - YYYY-MM-DD
     * @param {string} endDate - YYYY-MM-DD
     * @returns {boolean}
     */
    isDateRangeWithinOneYear(startDate, endDate) {
        if (!startDate || !endDate) return true;
        const start = new Date(`${startDate}T00:00:00`);
        const end = new Date(`${endDate}T00:00:00`);
        if (isNaN(start.getTime()) || isNaN(end.getTime())) return true;

        const maxEnd = new Date(start);
        maxEnd.setFullYear(maxEnd.getFullYear() + 1);
        return end.getTime() <= maxEnd.getTime();
    },

    /**
     * 校验自定义日期范围，避免一次查询跨度过大
     * @param {string} startDate - YYYY-MM-DD
     * @param {string} endDate - YYYY-MM-DD
     * @returns {boolean}
     */
    validateCustomDateRange(startDate, endDate) {
        if (!this.isDateRangeWithinOneYear(startDate, endDate)) {
            if (typeof Components !== 'undefined' && Components.showToast) {
                Components.showToast('自定义时间跨度最长不能超过一年', 'warning');
            }
            return false;
        }
        return true;
    },

    /**
     * 深拷贝对象
     * @param {Object} obj
     * @returns {Object}
     */
    deepClone(obj) {
        if (obj === null || typeof obj !== 'object') return obj;
        if (obj instanceof Date) return new Date(obj.getTime());
        if (Array.isArray(obj)) return obj.map(item => this.deepClone(item));
        const cloned = {};
        for (const key in obj) {
            if (obj.hasOwnProperty(key)) {
                cloned[key] = this.deepClone(obj[key]);
            }
        }
        return cloned;
    },

    /**
     * 防抖函数
     * @param {Function} func
     * @param {number} wait
     * @returns {Function}
     */
    debounce(func, wait = 300) {
        let timeout;
        return function executedFunction(...args) {
            const later = () => {
                clearTimeout(timeout);
                func(...args);
            };
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
        };
    },

    /**
     * 节流函数
     * @param {Function} func
     * @param {number} limit
     * @returns {Function}
     */
    throttle(func, limit = 300) {
        let inThrottle;
        return function executedFunction(...args) {
            if (!inThrottle) {
                func(...args);
                inThrottle = true;
                setTimeout(() => inThrottle = false, limit);
            }
        };
    },

    /**
     * 生成唯一ID
     * @returns {string}
     */
    generateId() {
        return Date.now().toString(36) + Math.random().toString(36).substr(2);
    },

    /**
     * 本地存储操作
     */
    storage: {
        get(key) {
            try {
                const item = localStorage.getItem(key);
                return item ? JSON.parse(item) : null;
            } catch (e) {
                return null;
            }
        },
        set(key, value) {
            try {
                localStorage.setItem(key, JSON.stringify(value));
                return true;
            } catch (e) {
                return false;
            }
        },
        remove(key) {
            try {
                localStorage.removeItem(key);
                return true;
            } catch (e) {
                return false;
            }
        },
        clear() {
            try {
                localStorage.clear();
                return true;
            } catch (e) {
                return false;
            }
        }
    },

    /**
     * 验证手机号
     * @param {string} phone
     * @returns {boolean}
     */
    isValidPhone(phone) {
        return /^1[3-9]\d{9}$/.test(phone);
    },

    /**
     * 验证邮箱
     * @param {string} email
     * @returns {boolean}
     */
    isValidEmail(email) {
        return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
    },

    /**
     * 验证金额：只允许数字和小数点，最多两位小数，不能为负数
     * @param {string} value - 输入值
     * @returns {Object} { isValid, cleanedValue, errorMessage }
     */
    validateAmount(value) {
        if (value === '' || value === null || value === undefined) {
            return { isValid: true, cleanedValue: '', errorMessage: '' };
        }
        
        const str = String(value);
        
        // 不允许负数
        if (str.startsWith('-')) {
            return { isValid: false, cleanedValue: str.replace(/^-/, ''), errorMessage: '金额不能为负数' };
        }
        
        // 只允许数字和小数点
        const cleaned = str.replace(/[^\d.]/g, '');
        
        // 处理多个小数点的情况
        const parts = cleaned.split('.');
        let finalValue = '';
        if (parts.length > 2) {
            finalValue = parts[0] + '.' + parts.slice(1).join('');
        } else {
            finalValue = cleaned;
        }
        
        // 限制小数点后最多两位
        const dotIndex = finalValue.indexOf('.');
        if (dotIndex !== -1 && finalValue.length > dotIndex + 3) {
            finalValue = finalValue.substring(0, dotIndex + 3);
        }
        
        // 验证最终值
        const num = parseFloat(finalValue);
        if (isNaN(num)) {
            return { isValid: false, cleanedValue: '', errorMessage: '请输入有效的金额' };
        }
        
        if (finalValue !== str) {
            return { isValid: true, cleanedValue: finalValue, errorMessage: '' };
        }
        
        return { isValid: true, cleanedValue: finalValue, errorMessage: '' };
    },

    /**
     * 验证数量：只允许正整数，必须大于0
     * @param {string} value - 输入值
     * @returns {Object} { isValid, cleanedValue, errorMessage }
     */
    validateQuantity(value) {
        if (value === '' || value === null || value === undefined) {
            return { isValid: false, cleanedValue: '', errorMessage: '数量不能为空' };
        }
        
        const str = String(value);
        
        // 只允许数字
        const cleaned = str.replace(/\D/g, '');
        
        if (cleaned === '') {
            return { isValid: false, cleanedValue: '', errorMessage: '请输入有效的数量' };
        }
        
        const num = parseInt(cleaned, 10);
        
        if (isNaN(num) || num <= 0) {
            return { isValid: false, cleanedValue: cleaned, errorMessage: '数量必须大于0' };
        }
        
        if (cleaned !== str) {
            return { isValid: true, cleanedValue: cleaned, errorMessage: '' };
        }
        
        return { isValid: true, cleanedValue: cleaned, errorMessage: '' };
    },

    /**
     * 验证非负整数：只允许数字，大于等于0
     * @param {string} value - 输入值
     * @returns {Object} { isValid, cleanedValue, errorMessage }
     */
    validateNonNegativeInteger(value) {
        if (value === '' || value === null || value === undefined) {
            return { isValid: true, cleanedValue: '0', errorMessage: '' };
        }
        
        const str = String(value);
        
        // 只允许数字
        const cleaned = str.replace(/\D/g, '');
        
        if (cleaned === '') {
            return { isValid: true, cleanedValue: '0', errorMessage: '' };
        }
        
        const num = parseInt(cleaned, 10);
        
        if (isNaN(num) || num < 0) {
            return { isValid: false, cleanedValue: '0', errorMessage: '请输入有效的数量' };
        }
        
        if (cleaned !== str) {
            return { isValid: true, cleanedValue: cleaned, errorMessage: '' };
        }
        
        return { isValid: true, cleanedValue: cleaned, errorMessage: '' };
    },

    /**
     * 显示输入框错误状态
     * @param {HTMLInputElement} input - 输入框元素
     * @param {string} message - 错误消息
     */
    showInputError(input, message) {
        if (!input) return;
        
        input.classList.add('input-error');
        
        let errorEl = input.parentElement.querySelector('.input-error-message');
        if (!errorEl) {
            errorEl = document.createElement('div');
            errorEl.className = 'input-error-message';
            input.parentElement.appendChild(errorEl);
        }
        errorEl.textContent = message;
        errorEl.style.display = 'block';
    },

    /**
     * 清除输入框错误状态
     * @param {HTMLInputElement} input - 输入框元素
     */
    clearInputError(input) {
        if (!input) return;
        
        input.classList.remove('input-error');
        
        const errorEl = input.parentElement.querySelector('.input-error-message');
        if (errorEl) {
            errorEl.style.display = 'none';
        }
    },

    /**
     * 显示加载状态
     * @param {HTMLElement} container
     */
    showLoading(container) {
        if (!container) return;
        container.innerHTML = `
            <div class="loading">
                <div class="spinner"></div>
                <span class="loading-text">加载中...</span>
            </div>
        `;
    },

    /**
     * 隐藏加载状态
     * @param {HTMLElement} container
     * @param {string} content
     */
    hideLoading(container, content = '') {
        if (!container) return;
        if (content) {
            container.innerHTML = content;
        }
    }
};

// 导出工具函数
window.Utils = Utils;

// 全局未处理的 Promise 拒绝错误处理（与小程序保持一致）
window.addEventListener('unhandledrejection', function(event) {
    console.error('Unhandled promise rejection:', event.reason);
    if (typeof Components !== 'undefined' && Components.showToast) {
        Components.showToast('操作失败，请重试', 'error');
    }
});
