import DataUtils from '../../../../mapboxgl/js/utils/DataUtils';

/**
 * 定义 MapGIS Common API Echarts图层类
 *
 * @alias EchartsLayer
 *
 * @summary <用于在地图上叠加Echarts图表的图层，使用前请确定已引入Echarts库资源>
 */
export default class EchartsLayer {
    /**
     * 构造函数
     * @param {Object} options - 图层选项
     */
    constructor(options) {
        /**
         * 地图对象
         * @type {Object}
         */
        this._map = options.map;

        /**
         * 视图对象
         * @type {Object}
         */
        this._view = options.view;

        /**
         * 图层ID
         * @type {String}
         */
        this._id = options.id || 'echarts_layer_' + new Date().getTime();

        /**
         * 图层标题
         * @type {String}
         */
        this._title = DataUtils.default(options.title, '');

        /**
         * 图层描述
         * @type {String}
         */
        this._description = DataUtils.default(options.description, '');

        /**
         * 版权所有
         * @type {String}
         */
        this._copyright = DataUtils.default(options.copyright, '');

        /**
         * 图层的范围。从元信息或数据中获取，默认为null表示取不到范围
         * @type {Object|null}
         */
        this._extent = options.extent || null;

        /**
         * echarts的构造参数
         * @type {Object}
         */
        this._echartsOptions = options.echartsOptions || {};

        /**
         * 图层透明度 (0-1)，0为完全透明，1为不透明
         * @type {Number}
         */
        this._opacity = DataUtils.default(options.opacity, 1);

        /**
         * 图层可见性，true则显示，false则隐藏
         * @type {Boolean}
         */
        this._visible = DataUtils.default(options.visible, true);

        /**
         * 最小显示比例尺，图层在视图中可见的最小比例尺(最缩小)
         * @type {Number}
         */
        this._minScale = DataUtils.default(options.minScale, 0);

        /**
         * 最大显示比例尺，图层在视图中可见的最大比例尺(最放大)
         * @type {Number}
         */
        this._maxScale = DataUtils.default(options.maxScale, 0);

        /**
         * Token键名
         * @type {String}
         */
        this._tokenKey = DataUtils.default(options.tokenKey, 'token');

        /**
         * Token值，只有当tokenValue存在时，才会绑定token
         * @type {String}
         */
        this._tokenValue = DataUtils.default(options.tokenValue, '');

        /**
         * Token附加类型
         * @type {String}
         */
        this._tokenAttachType = options.tokenAttachType || '';

        /**
         * 设置服务请求头
         * @type {Object}
         */
        this._headers = options.headers || {};

        /**
         * http请求方式
         * @type {String}
         */
        this._httpMethod = options.httpMethod || 'GET';

        /**
         * 图层支持能力。图层支持能力分为客户端能力和服务端能力，其中客户端能力包含cesium、leaflet、mapboxgl引擎能力。默认图层客户端能力：所有引擎支持图层加载；默认图层服务端能力为空
         * @type {Object}
         */
        this._capabilities = options.capabilities || {};

        /**
         * 额外属性，当前图层对象上不支持的属性，二次开发用户希望挂在图层对像上的属性可以存储到该属性中
         * @type {Object}
         */
        this._extendProps = options.extendProps || {};

        /**
         * 初始化图层的额外参数，可以通过该参数传入引擎原生的构造参数
         * @type {Object}
         */
        this._extensionOptions = options.extensionOptions || {};

        /**
         * 图层类型
         * @type {String}
         */
        this._type = options.type || 'echarts-layer';

        /**
         * 是否加载完毕
         * @type {Boolean}
         */
        this._loaded = false;

        /**
         * 请求失败后的错误信息
         * @type {Object|null}
         */
        this._loadError = null;

        /**
         * 图层加载状态: 'not-loaded' | 'loading' | 'loaded' | 'error'
         * @type {String}
         */
        this._loadStatus = 'not-loaded';

        /**
         * 图层实例
         * @type {Object|null}
         */
        this._instance = null;

        /**
         * 事件监听器集合
         * @type {Object}
         */
        this._eventListeners = {};
    }

    /** 公有方法 **/

    /**
     * 加载图层资源
     * @returns {Promise} 返回Promise对象
     */
    load() {
        return new Promise((resolve, reject) => {
            if (this._loadStatus === 'loaded') {
                resolve({ layer: this });
                return;
            }

            this._loadStatus = 'loading';

            try {
                // 引入 MapGIS Common API EchartsLayer 类
                const { EchartsLayer } = zondy.layer;
                const { initializeOptions, initializeCRS } = zondy.mapboxgl.util;

                // 初始化选项和坐标系
                const options = this._buildOptions();
                initializeOptions(options);
                initializeCRS(options);

                // 创建Echarts图层实例
                this._instance = new EchartsLayer(options);

                // 监听图层加载完毕事件
                this._instance.on('layerview-created', (result) => {
                    this._loaded = true;
                    this._loadStatus = 'loaded';
                    this._loadError = null;

                    // 触发加载完成事件
                    this._emitEvent('layerview-created', result);

                    resolve({ layer: this });
                });

                // 监听图层加载失败事件
                this._instance.on('layerview-error', (error) => {
                    this._loaded = false;
                    this._loadStatus = 'error';
                    this._loadError = error;

                    // 触发加载失败事件
                    this._emitEvent('layerview-error', error);

                    reject(error);
                });

                // 添加到地图
                if (this._map) {
                    this._map.add(this._instance);
                }

            } catch (error) {
                this._loaded = false;
                this._loadStatus = 'error';
                this._loadError = error;
                console.error('Echarts图层加载失败:', error);
                reject(error);
            }
        });
    }

    /**
     * 通过json构造EchartsLayer对象
     * @param {Object} json - JSON对象
     * @returns {EchartsLayer} EchartsLayer实例
     */
    static fromJSON(json) {
        const { EchartsLayer } = zondy.layer;
        const instance = EchartsLayer.fromJSON(json);
        return instance;
    }

    /**
     * 克隆并返回一个新图层
     * @returns {EchartsLayer} 新的图层对象
     */
    clone() {
        if (!this._instance) {
            console.warn('Echarts图层未加载，无法克隆');
            return null;
        }

        return this._instance.clone();
    }

    /**
     * 将图层转为json对象
     * @returns {Object} JSON对象
     */
    toJSON() {
        if (!this._instance) {
            console.warn('Echarts图层未加载');
            return {};
        }

        return this._instance.toJSON();
    }

    /**
     * 判断图层是否加载成功
     * @returns {Boolean} 图层是否加载成功
     */
    isLoaded() {
        return this._loadStatus === 'loaded';
    }

    /**
     * 刷新图层
     */
    refresh() {
        if (!this._instance) {
            console.warn('Echarts图层未加载');
            return;
        }

        this._instance.refresh();
    }

    /**
     * 销毁图层
     */
    destroy() {
        if (!this._instance) {
            return;
        }

        try {
            // 移除事件监听
            this._removeAllEventListeners();

            // 从地图中移除
            if (this._map) {
                this._map.remove(this._instance);
            }

            // 销毁图层实例
            this._instance.destroy();
            this._instance = null;
            this._loaded = false;
            this._loadStatus = 'not-loaded';
            this._loadError = null;

            this._emitEvent('layerview-remove', { layer: this });
        } catch (error) {
            console.error('Echarts图层销毁失败:', error);
        }
    }

    /**
     * 设置属性值或者属性路径对应的值
     * @param {String} path - 属性路径，可以传入单个属性或者一个属性的路径
     * @param {*} value - 属性值
     * @returns {Boolean} 是否设置成功
     */
    setProperty(path, value) {
        if (!this._instance) {
            console.warn('Echarts图层未加载');
            return false;
        }

        return this._instance.setProperty(path, value);
    }

    /**
     * 获取属性值
     * @param {String} path - 属性路径
     * @returns {*} 属性值
     */
    getProperty(path) {
        if (!this._instance) {
            console.warn('Echarts图层未加载');
            return undefined;
        }

        return this._instance.getProperty(path);
    }

    /**
     * 设置图层透明度
     * @param {Number} opacity - 透明度 (0-1)
     */
    setOpacity(opacity) {
        this._opacity = opacity;

        if (this._instance) {
            this._instance.opacity = opacity;
        }
    }

    /**
     * 设置图层显隐
     * @param {Boolean} visible - 是否可见
     */
    setVisible(visible) {
        this._visible = visible;

        if (this._instance) {
            this._instance.visible = visible;
        }
    }

    /**
     * 注册事件监听器
     * @param {String} eventName - 事件名称
     * @param {Function} callback - 回调函数
     */
    on(eventName, callback) {
        if (!this._eventListeners[eventName]) {
            this._eventListeners[eventName] = [];
        }
        this._eventListeners[eventName].push(callback);

        // 如果图层实例已存在，也注册到实例上
        if (this._instance) {
            this._instance.on(eventName, callback);
        }
    }

    /**
     * 移除事件监听器
     * @param {String} eventName - 事件名称
     * @param {Function} callback - 回调函数
     */
    off(eventName, callback) {
        if (this._eventListeners[eventName]) {
            this._eventListeners[eventName] = this._eventListeners[eventName].filter(
                cb => cb !== callback
            );
        }

        // 如果图层实例已存在，也从实例上移除
        if (this._instance && callback) {
            this._instance.off(eventName, callback);
        }
    }

    /** ==================== Getter/Setter ==================== */

    /**
     * 获取图层ID
     * @returns {String}
     */
    get id() {
        return this._id;
    }

    /**
     * 设置图层ID
     * @param {String} value - 图层ID
     */
    set id(value) {
        this._id = value;
        if (this._instance) {
            this._instance.id = value;
        }
    }

    /**
     * 获取图层标题
     * @returns {String}
     */
    get title() {
        return this._title;
    }

    /**
     * 设置图层标题
     * @param {String} value - 图层标题
     */
    set title(value) {
        this._title = value;
        if (this._instance) {
            this._instance.title = value;
        }
    }

    /**
     * 获取图层描述
     * @returns {String}
     */
    get description() {
        return this._description;
    }

    /**
     * 设置图层描述
     * @param {String} value - 图层描述
     */
    set description(value) {
        this._description = value;
        if (this._instance) {
            this._instance.description = value;
        }
    }

    /**
     * 获取版权信息
     * @returns {String}
     */
    get copyright() {
        return this._copyright;
    }

    /**
     * 设置版权信息
     * @param {String} value - 版权信息
     */
    set copyright(value) {
        this._copyright = value;
        if (this._instance) {
            this._instance.copyright = value;
        }
    }

    /**
     * 获取图层范围
     * @returns {Object|null}
     */
    get extent() {
        return this._extent;
    }

    /**
     * 设置图层范围
     * @param {Object} value - 图层范围
     */
    set extent(value) {
        this._extent = value;
        if (this._instance) {
            this._instance.extent = value;
        }
    }

    /**
     * 获取Echarts配置参数
     * @returns {Object}
     */
    get echartsOptions() {
        return this._echartsOptions;
    }

    /**
     * 设置Echarts配置参数
     * @param {Object} value - Echarts配置参数
     */
    set echartsOptions(value) {
        this._echartsOptions = value;
        if (this._instance) {
            this._instance.echartsOptions = value;
        }
    }

    /**
     * 获取图层透明度
     * @returns {Number}
     */
    get opacity() {
        return this._opacity;
    }

    /**
     * 设置图层透明度
     * @param {Number} value - 透明度 (0-1)
     */
    set opacity(value) {
        this._opacity = value;
        if (this._instance) {
            this._instance.opacity = value;
        }
    }

    /**
     * 获取图层可见性
     * @returns {Boolean}
     */
    get visible() {
        return this._visible;
    }

    /**
     * 设置图层可见性
     * @param {Boolean} value - 是否可见
     */
    set visible(value) {
        this._visible = value;
        if (this._instance) {
            this._instance.visible = value;
        }
    }

    /**
     * 获取最小显示比例尺
     * @returns {Number}
     */
    get minScale() {
        return this._minScale;
    }

    /**
     * 设置最小显示比例尺
     * @param {Number} value - 最小显示比例尺
     */
    set minScale(value) {
        this._minScale = value;
        if (this._instance) {
            this._instance.minScale = value;
        }
    }

    /**
     * 获取最大显示比例尺
     * @returns {Number}
     */
    get maxScale() {
        return this._maxScale;
    }

    /**
     * 设置最大显示比例尺
     * @param {Number} value - 最大显示比例尺
     */
    set maxScale(value) {
        this._maxScale = value;
        if (this._instance) {
            this._instance.maxScale = value;
        }
    }

    /**
     * 获取Token键名
     * @returns {String}
     */
    get tokenKey() {
        return this._tokenKey;
    }

    /**
     * 设置Token键名
     * @param {String} value - Token键名
     */
    set tokenKey(value) {
        this._tokenKey = value;
        if (this._instance) {
            this._instance.tokenKey = value;
        }
    }

    /**
     * 获取Token值
     * @returns {String}
     */
    get tokenValue() {
        return this._tokenValue;
    }

    /**
     * 设置Token值
     * @param {String} value - Token值
     */
    set tokenValue(value) {
        this._tokenValue = value;
        if (this._instance) {
            this._instance.tokenValue = value;
        }
    }

    /**
     * 获取Token附加类型
     * @returns {String}
     */
    get tokenAttachType() {
        return this._tokenAttachType;
    }

    /**
     * 设置Token附加类型
     * @param {String} value - Token附加类型
     */
    set tokenAttachType(value) {
        this._tokenAttachType = value;
        if (this._instance) {
            this._instance.tokenAttachType = value;
        }
    }

    /**
     * 获取服务请求头
     * @returns {Object}
     */
    get headers() {
        return this._headers;
    }

    /**
     * 设置服务请求头
     * @param {Object} value - 服务请求头
     */
    set headers(value) {
        this._headers = value;
        if (this._instance) {
            this._instance.headers = value;
        }
    }

    /**
     * 获取HTTP请求方式
     * @returns {String}
     */
    get httpMethod() {
        return this._httpMethod;
    }

    /**
     * 设置HTTP请求方式
     * @param {String} value - HTTP请求方式
     */
    set httpMethod(value) {
        this._httpMethod = value;
        if (this._instance) {
            this._instance.httpMethod = value;
        }
    }

    /**
     * 获取图层能力配置
     * @returns {Object}
     */
    get capabilities() {
        return this._capabilities;
    }

    /**
     * 设置图层能力配置
     * @param {Object} value - 图层能力配置
     */
    set capabilities(value) {
        this._capabilities = value;
        if (this._instance) {
            this._instance.capabilities = value;
        }
    }

    /**
     * 获取扩展属性
     * @returns {Object}
     */
    get extendProps() {
        return this._extendProps;
    }

    /**
     * 设置扩展属性
     * @param {Object} value - 扩展属性
     */
    set extendProps(value) {
        this._extendProps = value;
        if (this._instance) {
            this._instance.extendProps = value;
        }
    }

    /**
     * 获取扩展选项
     * @returns {Object}
     */
    get extensionOptions() {
        return this._extensionOptions;
    }

    /**
     * 设置扩展选项
     * @param {Object} value - 扩展选项
     */
    set extensionOptions(value) {
        this._extensionOptions = value;
        if (this._instance) {
            this._instance.extensionOptions = value;
        }
    }

    /**
     * 获取图层类型
     * @returns {String}
     */
    get type() {
        return this._type;
    }

    /**
     * 获取是否加载完毕
     * @returns {Boolean}
     */
    get loaded() {
        return this._loaded;
    }

    /**
     * 获取加载错误信息
     * @returns {Object|null}
     */
    get loadError() {
        return this._loadError;
    }

    /**
     * 获取加载状态
     * @returns {String}
     */
    get loadStatus() {
        return this._loadStatus;
    }

    /**
     * 获取图层实例
     * @returns {Object|null}
     */
    get instance() {
        return this._instance;
    }

    /** ==================== 私有方法 ==================== */

    /**
     * 构建图层配置选项
     * @returns {Object} 配置选项对象
     */
    _buildOptions() {
        const options = {
            id: this._id,
            title: this._title,
            description: this._description,
            copyright: this._copyright,
            extent: this._extent,
            echartsOptions: this._echartsOptions,
            opacity: this._opacity,
            visible: this._visible,
            minScale: this._minScale,
            maxScale: this._maxScale,
            tokenKey: this._tokenKey,
            tokenValue: this._tokenValue,
            tokenAttachType: this._tokenAttachType,
            headers: this._headers,
            httpMethod: this._httpMethod,
            capabilities: this._capabilities,
            extendProps: this._extendProps,
            extensionOptions: this._extensionOptions,
            type: this._type
        };

        return options;
    }

    /**
     * 触发事件
     * @param {String} eventName - 事件名称
     * @param {*} data - 事件数据
     */
    _emitEvent(eventName, data) {
        if (this._eventListeners[eventName]) {
            this._eventListeners[eventName].forEach(callback => {
                try {
                    callback(data);
                } catch (error) {
                    console.error(`事件 ${eventName} 回调执行失败:`, error);
                }
            });
        }
    }

    /**
     * 移除所有事件监听器
     */
    _removeAllEventListeners() {
        if (this._instance) {
            Object.keys(this._eventListeners).forEach(eventName => {
                this._eventListeners[eventName].forEach(callback => {
                    this._instance.off(eventName, callback);
                });
            });
        }
        this._eventListeners = {};
    }
}
