import {
  CallBack,
  ControlOptions,
  Controls,
  Listeners,
  ZoomOptions,
  FocusOptions,
  Location,
  Layers,
  LayerOption,
  BoundaryOption,
} from './types'

const defaultListeners = {
  load: () => console.error('on：此地图不存在 load 监听事件！'),
  zoom: () => console.error('on：此地图不存在 zoom 监听事件！'),
  move: () => console.error('on：此地图不存在 move 监听事件！'),
  blur: () => console.error('on：此地图不存在 blur 监听事件！'),
  focus: () => console.error('on：此地图不存在 focus 监听事件！'),
  drag: () => console.error('on：此地图不存在 drag 监听事件！'),
  resize: () => console.error('on：此地图不存在 resize 监听事件！'),
  click: () => console.error('on：此地图不存在 click 监听事件！'),
  dblclick: () => console.error('on：此地图不存在 dblclick 监听事件！'),
  mousewheel: () => console.error('on：此地图不存在 mousewheel 监听事件！'),
}

const defaultControls = {
  home: () => console.error('set：此地图不存在 home 控件！'),
  zoom: () => console.error('set：此地图不存在 home 控件！'),
  compass: () => console.error('set：此地图不存在 home 控件！'),
  scale: () => console.error('set：此地图不存在 scale 控件！'),
  fullScreen: () => console.error('set：此地图不存在 fullScreen 控件！'),
  layerList: () => console.error('set：此地图不存在 layerList 控件！'),
  measureLine: () => console.error('set：此地图不存在 measureLine 控件！'),
  measureArea: () => console.error('set：此地图不存在 measureArea 控件！'),
  basemapToggle: () => console.error('set：此地图不存在 basemapToggle 控件！'),
  underguroundSwitch: () =>
    console.error('set：此地图不存在 underguroundSwitch 控件！'),
  bMapGallery: () => console.error('set：此地图不存在 bMapGallery 控件！'),
  bMapGalleryexpand: () =>
    console.error('set：此地图不存在 bMapGalleryexpand 控件！'),
}

const defaultLayers = {
  point: () => console.error('add：此地图不存在 point 覆盖物！'),
  line: () => console.error('add：此地图不存在 line 覆盖物！'),
  polygon: () => console.error('add：此地图不存在 polygon 覆盖物！'),
  boundary: () => console.error('add：此地图不存在 boundary 覆盖物！'),
}

export default abstract class MyMap {
  protected map
  protected _listeners: Listeners = defaultListeners
  protected _controls: Controls = defaultControls
  protected _layers: Layers = defaultLayers

  constructor(instance: any) {
    this.map = instance
  }

  /**
   *  原始地图实例
   * （主要适用于调用原始地图的方法、功能）
   */
  get instance(): any {
    return this.map
  }

  /**
   * 监听事件
   * @param name 事件名称
   * @param cb 回调函数
   */
  on<K extends keyof Listeners>(name: K, cb: CallBack) {
    this._listeners[name](cb)
    return this
  }

  /**
   * 添加控件
   * @param name 控件名称
   * @param options 控件参数:
   */
  set<K extends keyof Controls>(name: K, options: ControlOptions = {}) {
    if (options.show === undefined) options.show = true
    if (options.position === undefined) options.position = 'top-right'
    this._controls[name](options)
    return this
  }

  /**
   * 添加覆盖物
   * @param type 覆盖物类型
   * @param data 覆盖物数据
   */
  add<K extends keyof Layers>(type: K, data: LayerOption) {
    return this._layers[type](data)
  }

  /**
   * zoom in
   * @param options 参数
   */
  abstract zoomIn(options?: ZoomOptions): void
  /**
   * zoom out
   * @param options 参数
   */
  abstract zoomOut(options?: ZoomOptions): void
  /**
   * zoom to
   * @param level 等级
   * @param options 参数
   */
  abstract zoomTo(level: number, options?: ZoomOptions): void
  /**
   * 聚焦
   * @param location 坐标
   * @param options 参数
   */
  abstract focus(location: Location, options?: FocusOptions): void

  /**
   * 移除覆盖物
   * @param layer 覆盖物
   */
  abstract remove(layer: unknown): void

  /**
   * 添加边界
   * @param option 配置项
   */
  abstract addBoundary(option: BoundaryOption): { remove: () => void }
}
