// image-upload.js - 修复完善版
(function($, window, document) {
    'use strict';

    // 默认配置
    const DEFAULT_CONFIG = {
        uploadUrl: '/common/upload',
        maxFiles: 1,
        maxSize: 5 * 1024 * 1024, // 5MB
        allowedTypes: ['image/jpeg', 'image/png', 'image/gif', 'image/jpg', 'image/webp'],
        previewWidth: 120,
        previewHeight: 120,
        inputName: 'images[]',
        showRemove: true,
        showError: true,
        multiple: false,
        initialFiles: [] // 新增：初始文件数组
    };

    /**
     * 图片上传组件构造函数
     */
    function ImageUpload(container, options) {
        this.container = $(container);
        this.config = $.extend({}, DEFAULT_CONFIG, options);
        this.files = [];
        this.initialized = false;
        this.init();
    }

    ImageUpload.prototype = {
        init: function() {
            this.createHTML();
            this.bindEvents();

            // 初始化后设置初始文件
            if (this.config.initialFiles && this.config.initialFiles.length > 0) {
                setTimeout(() => {
                    this.setFiles(this.config.initialFiles);
                }, 50);
            }

            this.initialized = true;
        },

        createHTML: function() {
            const config = this.config;

            const html = `
                <div class="image-upload-wrapper">
                    <div class="upload-container">
                        <div class="preview-area"></div>
                        <div class="upload-dropzone">
                            <div class="upload-content">
                                <i class="fa fa-cloud-upload upload-icon"></i>
                                <div class="upload-text">
                                    <div class="upload-title">点击上传图片</div>
                                    <div class="upload-subtitle">
                                        支持 ${this.getAllowedTypesString()}，最大 ${this.formatFileSize(config.maxSize)}
                                    </div>
                                </div>
                            </div>
                            <input type="file" class="file-input" 
                                   ${config.multiple ? 'multiple' : ''}
                                   accept="${this.getAllowedTypesAccept()}">
                        </div>
                    </div>
                    <div class="hidden-inputs"></div>
                    <div class="error-message" style="display: none;"></div>
                </div>
            `;

            this.container.html(html);

            this.$uploadContainer = this.container.find('.upload-container');
            this.$dropzone = this.container.find('.upload-dropzone');
            this.$fileInput = this.container.find('.file-input');
            this.$previewArea = this.container.find('.preview-area');
            this.$hiddenInputs = this.container.find('.hidden-inputs');
            this.$error = this.container.find('.error-message');
        },

        bindEvents: function() {
            const self = this;

            // 文件选择变化事件
            this.$fileInput.on('change', function(e) {
                const files = Array.from(this.files);
                self.handleFileSelect(files);
                // 重置input，以便可以选择相同的文件
                $(this).val('');
            });

            // 拖拽事件
            this.$uploadContainer.on('dragover', function(e) {
                e.preventDefault();
                e.stopPropagation();
                $(this).addClass('dragover');
            });

            this.$uploadContainer.on('dragleave', function(e) {
                e.preventDefault();
                e.stopPropagation();
                $(this).removeClass('dragover');
            });

            this.$uploadContainer.on('drop', function(e) {
                e.preventDefault();
                e.stopPropagation();
                $(this).removeClass('dragover');

                const files = Array.from(e.originalEvent.dataTransfer.files);
                self.handleFileSelect(files);
            });

            // 删除按钮事件（使用事件委托）
            this.$previewArea.on('click', '.preview-remove', function(e) {
                e.stopPropagation();
                const index = $(this).closest('.preview-item').data('index');
                self.removeFile(index);
            });
        },

        handleFileSelect: function(files) {
            const config = this.config;
            const errors = [];

            // 检查文件数量
            const remainingSlots = config.maxFiles - this.files.length;
            if (files.length > remainingSlots) {
                errors.push(`最多只能上传 ${config.maxFiles} 个文件`);
                files = files.slice(0, remainingSlots);
            }

            // 验证每个文件
            files.forEach(file => {
                const fileErrors = this.validateFile(file);
                if (fileErrors.length > 0) {
                    errors.push(`"${file.name}"：${fileErrors.join('，')}`);
                } else {
                    this.uploadFile(file);
                }
            });

            // 显示错误信息
            if (errors.length > 0 && config.showError) {
                this.showError(errors.join('<br>'));
            }
        },

        validateFile: function(file) {
            const config = this.config;
            const errors = [];

            // 检查文件类型
            const allowedTypes = config.allowedTypes.map(type => type.toLowerCase());
            const fileType = file.type.toLowerCase();

            if (!allowedTypes.includes(fileType)) {
                errors.push('文件类型不支持');
            }

            // 检查文件大小
            if (file.size > config.maxSize) {
                errors.push(`文件过大（最大${this.formatFileSize(config.maxSize)}）`);
            }

            return errors;
        },

        uploadFile: function(file) {
            const self = this;
            const config = this.config;

            // 创建预览
            const previewIndex = this.files.length;
            this.createPreview(file, previewIndex);

            // 设置上传中状态
            this.$uploadContainer.addClass('uploading');

            // 创建FormData
            const formData = new FormData();
            formData.append('file', file);

            // 发送上传请求
            $.ajax({
                url: config.uploadUrl,
                type: 'POST',
                data: formData,
                processData: false,
                contentType: false,
                dataType: 'json',
                xhr: function() {
                    const xhr = new XMLHttpRequest();
                    const $progress = self.$previewArea.find(`.preview-item[data-index="${previewIndex}"] .upload-progress-bar`);

                    xhr.upload.addEventListener('progress', function(e) {
                        if (e.lengthComputable) {
                            const percent = Math.round((e.loaded / e.total) * 100);
                            $progress.css('width', percent + '%');
                        }
                    }, false);

                    return xhr;
                },
                success: function(response) {
                    self.$uploadContainer.removeClass('uploading');

                    if (response.code === 0) { // 假设0表示成功
                        // 保存文件信息
                        self.files.push({
                            url: response.url,
                            name: file.name,
                            size: file.size,
                            file: file
                        });

                        // 更新预览
                        const $previewItem = self.$previewArea.find(`.preview-item[data-index="${previewIndex}"]`);
                        $previewItem.find('img').attr('src', response.url);
                        $previewItem.find('.preview-info').text('上传完成');

                        // 添加隐藏字段
                        self.addHiddenField(response.url, previewIndex);

                        // 如果有图片，添加has-preview类
                        if (self.files.length > 0) {
                            self.$uploadContainer.addClass('has-preview');
                        }

                        // 触发成功事件
                        $(self.container).trigger('upload.success', {
                            file: file,
                            url: response.url,
                            index: previewIndex
                        });
                    } else {
                        self.removeFile(previewIndex);
                        self.showError(response.msg || '上传失败');
                        $(self.container).trigger('upload.error', {
                            file: file,
                            error: response.msg || '上传失败'
                        });
                    }
                },
                error: function(xhr, status, error) {
                    self.$uploadContainer.removeClass('uploading');
                    self.removeFile(previewIndex);
                    self.showError('上传失败：' + (error || '网络错误'));
                    $(self.container).trigger('upload.error', {
                        file: file,
                        error: error || '网络错误'
                    });
                }
            });
        },

        createPreview: function(file, index) {
            const reader = new FileReader();
            const self = this;

            reader.onload = function(e) {
                const html = `
                    <div class="preview-item" data-index="${index}">
                        <img src="${e.target.result}" alt="${file.name}">
                        <div class="preview-remove" title="删除图片">×</div>
                        <div class="preview-info">上传中...</div>
                        <div class="upload-progress">
                            <div class="upload-progress-bar"></div>
                        </div>
                    </div>
                `;

                self.$previewArea.append(html);

                // 如果有图片，添加has-preview类
                if (self.files.length >= 0) {
                    self.$uploadContainer.addClass('has-preview');
                }
            };

            reader.readAsDataURL(file);
        },

        removeFile: function(index) {
            // 从数组中移除
            this.files.splice(index, 1);

            // 移除预览
            this.$previewArea.find(`.preview-item[data-index="${index}"]`).remove();

            // 移除隐藏字段
            this.$hiddenInputs.find(`input[data-index="${index}"]`).remove();

            // 更新其他元素的索引
            this.$previewArea.find('.preview-item').each(function(i, el) {
                const $el = $(el);
                const currentIndex = parseInt($el.data('index'));
                if (currentIndex > index) {
                    $el.data('index', currentIndex - 1);
                }
            });

            // 更新隐藏字段的索引
            this.$hiddenInputs.find('input').each(function(i, el) {
                const $el = $(el);
                const currentIndex = parseInt($el.data('index'));
                if (currentIndex > index) {
                    $el.data('index', currentIndex - 1);
                }
            });

            // 如果没有图片，移除has-preview类
            if (this.files.length === 0) {
                this.$uploadContainer.removeClass('has-preview');
            }

            $(this.container).trigger('file.remove', { index: index });
        },

        addHiddenField: function(url, index) {
            const $input = $('<input>', {
                type: 'hidden',
                name: this.config.inputName,
                value: url,
                'data-index': index
            });

            this.$hiddenInputs.append($input);
        },

        showError: function(message) {
            if (!this.config.showError) return;

            this.$error.html(message).show();

            setTimeout(() => {
                this.$error.fadeOut();
            }, 5000);
        },

        getAllowedTypesString: function() {
            const extensions = this.config.allowedTypes.map(type => {
                const parts = type.split('/');
                return parts[1] ? parts[1].toUpperCase() : '';
            }).filter(Boolean);

            return extensions.join('、');
        },

        getAllowedTypesAccept: function() {
            return this.config.allowedTypes.join(',');
        },

        formatFileSize: function(bytes) {
            if (bytes === 0) return '0 B';

            const k = 1024;
            const sizes = ['B', 'KB', 'MB', 'GB'];
            const i = Math.floor(Math.log(bytes) / Math.log(k));

            return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
        },

        // 公共方法
        getFiles: function() {
            return this.files.map(file => file.url);
        },

        getFileObjects: function() {
            return this.files;
        },

        clear: function() {
            this.files = [];
            this.$previewArea.empty();
            this.$hiddenInputs.empty();
            this.$error.hide();
            this.$uploadContainer.removeClass('has-preview');
        },

        setFiles: function(urls) {
            this.clear();

            if (!urls || !Array.isArray(urls)) {
                urls = [];
            }

            // 过滤掉空值
            urls = urls.filter(url => url && url.trim() !== '');

            urls.forEach((url, index) => {
                this.files.push({
                    url: url,
                    name: '已上传图片',
                    size: 0
                });

                const html = `
                    <div class="preview-item" data-index="${index}">
                        <img src="${url}" alt="图片" onerror="this.src='data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\' width=\'100\' height=\'100\'><rect width=\'100\' height=\'100\' fill=\'%23f0f0f0\'/><text x=\'50\' y=\'50\' font-size=\'12\' text-anchor=\'middle\' fill=\'%23999\'>图片加载失败</text></svg>';">
                        <div class="preview-remove" title="删除图片">×</div>
                        <div class="preview-info">已上传</div>
                    </div>
                `;

                this.$previewArea.append(html);
                this.addHiddenField(url, index);

                // 添加has-preview类
                this.$uploadContainer.addClass('has-preview');
            });

            // 触发设置完成事件
            $(this.container).trigger('files.set', { urls: urls });

            return this;
        },

        destroy: function() {
            this.$fileInput.off();
            this.$uploadContainer.off();
            this.$previewArea.off();
            this.container.empty();
            this.container.removeData('imageUpload');
        }
    };

    // jQuery插件 - 简化版本
    $.fn.imageUpload = function(options) {
        const args = Array.prototype.slice.call(arguments, 1);

        return this.each(function() {
            const $this = $(this);
            let instance = $this.data('imageUpload');

            // 如果是方法调用
            if (typeof options === 'string') {
                const method = options;
                if (instance && typeof instance[method] === 'function') {
                    return instance[method].apply(instance, args);
                }
                throw new Error(`方法 "${method}" 不存在`);
            }

            // 如果是初始化
            if (!instance) {
                instance = new ImageUpload(this, options || {});
                $this.data('imageUpload', instance);
            }

            return instance;
        });
    };

})(jQuery, window, document);