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

/**
 * 定义 MapGIS Common API iServer场景图层类
 *
 * @alias ISSceneLayer
 *
 * @summary <用于接入SuperMap iServer发布的三维服务，基于 MapGIS Client for JavaScript Common 模块>
 */
export default class ISSceneLayer {
    /**
     * 构造函数
     * @param {Object} options - 图层选项
     * @param {Object} options.map - 地图对象(mapboxgl.Map 实例)
     * @param {String} options.url - 服务基地址 (http://{ip}:{port}/iserver/services/{服务名}/rest/realspace)
     * @param {String} [options.id] - 图层ID(可选,不传则自动生成)
     * @param {String} [options.description=''] - 描述信息
     * @param {Object} [options.extent=null] - 场景图层范围
     * @param {Object} [options.position={}] - 模型位置
     * @param {String} [options.sceneName=''] - 服务名
     * @param {Array} [options.scenes=[]] - 场景集合
     * @param {Object} [options.spatialReference={}] - 图层坐标系对象
     * @param {String} [options.version=''] - 服务版本号
     * @param {Object} [options.capabilities={}] - 图层支持能力
     */
    constructor(options) {
        /**
         * 地图对象
         * @type {Object}
         */
        this._map = options.map;

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

        this._layer = null

        /**
         * 服务基地址
         * @type {String}
         */
        this._url = DataUtils.default(options.url, '');

        /**
         * 图层ID
         * @type {String}
         */
        this._layerId = DataUtils.default(options.id, 'is_scene_layer_' + new Date().getTime());

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

        /**
         * 场景图层范围
         * @type {Object|null}
         */
        this._extent = DataUtils.default(options.extent, null);

        /**
         * 模型位置
         * @type {Object}
         */
        this._position = DataUtils.default(options.position, {});

        /**
         * 服务名
         * @type {String}
         */
        this._sceneName = DataUtils.default(options.sceneName, '');

        /**
         * 场景集合
         * @type {Array}
         */
        this._scenes = DataUtils.default(options.scenes, []);

        /**
         * 图层坐标系对象
         * @type {Object}
         */
        this._spatialReference = DataUtils.default(options.spatialReference, {});

        /**
         * 图层类型
         * @type {String}
         */
        this._type = DataUtils.default(options.type, 'is-scene-layer');

        /**
         * 服务版本号
         * @type {String}
         */
        this._version = DataUtils.default(options.version, '');

        /**
         * 图层支持能力
         * @type {Object}
         */
        this._capabilities = DataUtils.default(options.capabilities, {});

        /**
         * 所有子图层
         * @type {Object|null}
         */
        this._allSublayers = null;

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

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

        this._isFlyTo = DataUtils.default(options.isFlyTo, true);
    }

    _buildOptions() {
        const options = {
            url: this._url,
            description: this._description,
            position: this._position,
            sceneName: this._sceneName,
            scenes: this._scenes,
            spatialReference: this._spatialReference,
            version: this._version,
            capabilities: this._capabilities,
            type: this._type,
        };

        if (this._extent) {
            options.extent = this._extent;
        }

        return options;
    }

    /** ==================== Core Methods ==================== */

    /**
     * 加载图层资源
     * @description 不加载图层到地图,仅获取图层信息
     * @returns {Promise<ISSceneLayer>} 返回图层实例的 Promise
     */
    load() {
        return new Promise((resolve, reject) => {
            try {
                if (!this._layer) {
                    const opts = this._buildOptions();
                    // 引入 MapGIS Common API ISSceneLayer 类
                    const { ISSceneLayer } = zondy.layer;
                    const { initializeOptions, initializeCRS } = zondy.mapboxgl.util;

                    initializeOptions(opts);
                    initializeCRS(opts);

                    this._layer = new ISSceneLayer(opts);
                }

                // 监听图层加载完成事件
                const handler = (result) => {
                    this._layer.off('layerview-created', handler);
                    this._allSublayers = this._layer.allSublayers || null;
                    resolve(this);
                };

                this._layer.on('layerview-created', handler);

                // 如果已经加载完成,直接返回
                if (this._layer.loadStatus === 'loaded') {
                    resolve(this);
                }
            } catch (error) {
                reject(error);
            }
        });
    }

    /**
     * 加载图层到地图
     * @description 调用 zondy.layer.ISSceneLayer 加载图层数据,并添加到 Mapbox GL 地图中
     * @returns {void}
     */
    loadLayer() {
        if (this.hasLayer()) return;

        const { ISSceneLayer } = zondy.layer;
        const { initializeOptions, initializeCRS } = zondy.mapboxgl.util;

        const opts = this._buildOptions();
        initializeOptions(opts);
        initializeCRS(opts);

        const layer = new ISSceneLayer(opts);
        this._layer = layer;

        // 将图层添加到 MapGIS 地图对象
        this.addToMapGisMap();

        // 监听图层加载完成事件
        layer.on('layerview-created', (result) => {
            this._allSublayers = layer.allSublayers || null;
            // 视点跳转
            this._isFlyTo && gisView.goTo({
                layer: result.layer
            });
        });
    }

    addToMapGisMap() {
        this._map.add(this._layer);
    }

    /**
     * 显示/隐藏图层
     * @param {Boolean} isShow - 是否显示图层(true: 显示,false: 隐藏)
     */
    showLayer(isShow) {
        if (this._layer) {
            this._layer.visible = isShow;
        }
    }

    /**
     * 判断图层是否已加载
     * @returns {Boolean}
     */
    hasLayer() {
        if (this._layer && this._layer.isLoaded) {
            return true;
        }
        return false;
    }

    /**
     * 移除图层
     */
    removeLayer() {
        if (this._layer) {
            this._layer.remove();
            this._layer = null;
        }
    }

    /**
     * 通过子图层ID来查询子图层
     * @param {String} id - 子图层id
     * @returns {Object|null} 查询到的子图层
     */
    findSublayerById(id) {
        if (!this._layer) {
            console.warn('iServer场景图层未加载');
            return null;
        }
        return this._layer.findSublayerById(id);
    }

    /**
     * 通过传入的json构造并返回一个新的图层对象
     * @param {Object} json - JSON对象
     * @returns {ISSceneLayer} 图层对象
     */
    static fromJSON(json) {
        const { ISSceneLayer } = zondy.layer;
        return ISSceneLayer.fromJSON(json);
    }

    /**
     * 克隆图层对象
     * @returns {ISSceneLayer} 克隆后的图层对象
     */
    clone() {
        if (!this._layer) {
            console.warn('iServer场景图层未加载，无法克隆');
            return null;
        }
        return this._layer.clone();
    }

    /**
     * 导出为json对象
     * @returns {Object} JSON对象
     */
    toJSON() {
        if (!this._layer) {
            console.warn('iServer场景图层未加载');
            return {};
        }
        return this._layer.toJSON();
    }

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

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

    /**
     * 获取服务URL
     * @returns {String}
     */
    get url() {
        return this._url;
    }

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