    import Zondy from '../Zondy'
    import { Log, defaultValue, defined } from '../../util'

    /**
     * 空间参考系
     * <br><br>[ES5引入方式]：<br/>
     * Zondy.SpatialReference() <br/>
     * [ES6引入方式]：<br/>
     * import { SpatialReference } from "@mapgis/webclient-common" <br/>
     * <br/>
     * @class SpatialReference
     * @moduleEX GeometryModule
     * @param {Object|String} options 构造参数
     * @param {Number|undefined} [options.wkid] 空间参考系的wkid
     * @param {String|undefined} [options.wkt] 空间参考系Well Known Text 或 proj4js字符串,仅支持proj4js能够支持的字符串。OGC WKT标准{@link https://www.ogc.org/standard/wkt-crs/}, EPSG坐标系查询{@link https://epsg.io/}
     * @param {String|undefined} [options.unit] 空间参考系单位
     */
    class SpatialReference {
      constructor(options) {
        options = defaultValue(options, {})
        const { wkid, wkt } = this._parseSpatialReferenceOptions(options)
        /**
         * 投影坐标系的id
         * @member {Number} SpatialReference.prototype.wkid
         */
        this.wkid = wkid
        /**
         * 投影坐标系的描述
         * @member {String|undefined} SpatialReference.prototype.wkt
         */
        this.wkt = wkt
        /**
         * 投影坐标系的描述
         * @member {String|undefined} SpatialReference.prototype.unit
         */
        this.unit = options.unit
      }

      /**
       * 是否是WGS84相关坐标系
       * @readonly
       * @type {Boolean}
       */
      get isWGS84() {
        return this.wkid === 4326
      }

      /**
       * 是否是地理坐标系
       * @readonly
       * @type {Boolean}
       */
      get isGeographic() {
        if ([4326, 4490, 4610, 4214].indexOf(this.wkid) > -1) {
          return true
        }
        return false
      }

      /**
       * 是否是Web墨卡托坐标系
       * @readonly
       * @type {Boolean}
       */
      get isWebMercator() {
        if ([102113, 102100, 900913, 3857].indexOf(this.wkid) > -1) {
          return true
        }
        return false
      }

      /**
       *  坐标系否支持环绕国际日期线，当参考系是Web Mercator或WGS84
       * @readonly
       * @type {Boolean}
       */
      get isWrappable() {
        if (
          [4326, 4490, 4610, 4214, 102113, 102100, 900913, 3857].indexOf(
            this.wkid
          ) > -1
        ) {
          return true
        }
        return false
      }

      /**
       *  一个便捷的Web墨卡托对象，只有当类型为Web墨卡托时才有
       * @readonly
       * @type {SpatialReference}
       */
      get WebMercator() {
        return this.isWebMercator ? this.clone() : undefined
      }

      /**
       *  一个便捷的WGS84对象，只有当类型为WGS84时才有
       * @readonly
       * @type {SpatialReference}
       */
      get WGS84() {
        return this.isGeographic ? this.clone() : undefined
      }

      /**
       * @private
       * @description: 解析传入的options
       * @param {*} options
       * @return {*}
       */
      _parseSpatialReferenceOptions(options) {
        let wkid = 4326
        let wkt
        if (typeof options === 'string') {
          const req = /^(EPSG|epsg)(:)?\d+$/
          const reqWkid = /\d+$/
          const wkidStr = options.match(reqWkid)
          if (req.test(options) && wkidStr) {
            wkid = parseInt(wkidStr[0])
            wkt = undefined
          } else {
            // 字符串设置为wkt
            wkt = options
            wkid = undefined
          }
        } else if (typeof options === 'object') {
          if (defined(options['wkid'])) {
            wkid = parseInt(options['wkid'])
          }
          if (options['wkt']) {
            wkt = options['wkt']
            wkid = undefined
          }
        } else {
          Log.error('无法解析传入的空间参考系参数')
        }
        return {
          wkid,
          wkt
        }
      }

      /**
       * 克隆几何对象
       * @return {Geometry} 克隆后的几何对象
       */
      clone() {
        return new SpatialReference(this.toJSON())
      }

      /**
       * 将JSON里的数据导入到几何中
       * @param {Object} json JSON对象
       */
      static fromJSON(json) {
        json = defaultValue(json, {})
        return new SpatialReference(json)
      }

      /**
       * 导出为json对象
       * @return {Object} json对象
       */
      toJSON() {
        return {
          wkid: this.wkid,
          wkt: this.wkt
        }
      }

      /**
       * 导出为字符串(此处语义和设计不符，为igs服务参数专用，后续需要修改)
       * @private
       * @return {String} 坐标系字符串
       */
      toString() {
        let wkt = ''
        switch (this.wkid) {
          case 4326:
            wkt = 'EPSG:4326'
            break
          case 3857:
            wkt = 'EPSG:3857'
            break
          default:
            wkt = this.wkt
        }
        return wkt
      }

      /**
       * 判断坐标系对象的wkid和wkt的值是否相等
       * @param {SpatialReference | Object} spatialReference 坐标系对象
       * @return {Boolean} wkid和wkt的值是否相等
       * */
      equals(spatialReference) {
        if (!(spatialReference instanceof SpatialReference)) {
          if (
            !(
              spatialReference instanceof Object &&
              spatialReference.hasOwnProperty('wkid') &&
              spatialReference.hasOwnProperty('wkt')
            )
          ) {
            throw new Error('spatialReference的格式不正确！')
          }
        }

        // 暂时无法保证wkt值一致，因此只比较wkid一致即可
        if (this.wkid === spatialReference.wkid) {
          return true
        } else if (
          this.wkt &&
          spatialReference.wkt &&
          this.wkt === spatialReference.wkt
        ) {
          return true
        }
        return false
      }
    }

    Zondy.SpatialReference = SpatialReference
    export default SpatialReference