import { objectFromMap } from "./ui_utils.js";

class PDFAnnotationStorage {
  constructor(annotationView, numPages, eventBus) {
    this._storage = new Map();
    this._modified = false;
    this.annotationPages = Array(numPages)
    this.annotationView = annotationView
    this.numPages = numPages
    this._eventBus = eventBus
  }

  /**
   * 获取指定注释key的值或返回默认值
   *
   * @public
   * @memberof PDFAnnotationStorage
   * @param {string} key
   * @param {Object} defaultValue
   * @returns {Object}
   */
  getValue(key, defaultValue) {
    const value = this._storage.get(key);
    if (value === undefined) {
      return defaultValue;
    }

    return Object.assign(defaultValue, value);
  }
  /**
   * 获取指定注释key的值
   *
   * @public
   * @memberof PDFAnnotationStorage
   * @param {string} key
   * @returns {Object}
   */
  getRawValue(key) {
    return this._storage.get(key);
  }
  /**
   * 从storage中删除指定的key值
   * @param {string} key
   */
  remove(key) {
    const obj = this.getRawValue(key);
    if (!obj) return
    if (this.annotationPages[obj.pageIndex]) {
      const boxObj = this.annotationPages[obj.pageIndex].annotations.get(key);
      this.annotationPages[obj.pageIndex].annotations.delete(key);
      boxObj?.annotationBox.remove();
      if (this.annotationPages[obj.pageIndex].annotations.size === 0) {
        this.annotationPages[obj.pageIndex].annotationPage.remove();
        this.annotationPages[obj.pageIndex] = undefined
      }
    }
    this._storage.delete(key);
    this._eventBus.dispatch("annotationsCountChanged", {
      annotationsCount: this.size
    })
    if (this._storage.size === 0) {
      this.resetModified();
    }
  }

  cleanup() {
    const editor = this._storage.values().next().value
    if (editor) {
      editor.parent._uiManager.removeAllAnnotations()
    }
  }

  /**
   * 设置指定的key值
   *
   * @public
   * @memberof PDFAnnotationStorage
   * @param {string} key
   * @param {Object} value
   */
  setValue(key, value) {
    const obj = this._storage.get(key);
    let modified = false;
    if (obj !== undefined) {
      obj.add(value)
    } else {
      modified = true;
      this._storage.set(key, value);
      if (value.name === 'stickyAnnotation') {
        this._eventBus.dispatch("annotationsCountChanged", {
          annotationsCount: this.size
        })
      }
    }
    if (modified) {
      this.setModified();
      if (value.name !== "inkEditor") {
        if (!this.annotationPages[value.pageIndex]) {
          this.annotationPages[value.pageIndex] = {}
          this.annotationPages[value.pageIndex].annotations = new Map()
          const pageNumber = document.createElement("div");
          pageNumber.className = "pageNumber";
          pageNumber.innerText = `Page ${value.pageIndex + 1}`;
          const annotationPage = document.createElement("div");
          annotationPage.className = "annotationPage";
          this.annotationPages[value.pageIndex].annotationPage = annotationPage;
          annotationPage.append(pageNumber)
          this.annotationView.append(annotationPage);
        }
        const annotationDetail = document.createElement('div');
        annotationDetail.className = "annotationBox"
        annotationDetail.innerHTML = `
          <div class="annotationGroup">
            <div class="annotationContent">
              <div color="#FF2600" class="iconWrapper" style="margin-right: 8px;">
                <svg width="24" height="24" viewBox="0 0 24 24"><g fill="none" fill-rule="evenodd"><path d="M0 0h24v24H0z"></path><path d="M21.6 3.6V18H12l-6 3.6V18H2.4V3.6h19.2zM18 11.4H6v1.8h12v-1.8zm-4.8-4.2H6V9h7.2V7.2z" fill="#273C62"></path></g></svg>
              </div>
              <div class="contentBox">${value._content}</div>
            </div>
            <span>${value.annotationObj.obj_attr.date.replace('_', ' ')}</span>
          </div>
          <div title="Delete" class="iconWrapper delete" style="width: 16px; height: 16px; position: absolute; top: 4px; right: 4px;">
            <svg width="16" height="16" viewBox="0 0 16 16"><g fill="none" fill-rule="evenodd"><path d="M0 0h16v16H0z"></path><path d="M13.303 3.404L8.707 8l4.596 4.596-.707.707L8 8.706l-4.595 4.597-.707-.707L7.292 8 2.697 3.404l.707-.707L8 7.293l4.596-4.596.707.707z" fill="#757780"></path></g></svg>
          </div>`;
        value.annotationBox = annotationDetail;
        this.annotationPages[value.pageIndex].annotations.set(key, value);
        const deleteButton = annotationDetail.querySelector('.delete');
        deleteButton.addEventListener('click', value.remove.bind(value))
        this.annotationPages[value.pageIndex].annotationPage.append(annotationDetail)
      }
    }
  }
  /**
   * 判断storage中是否存在指定key值
   * @param {string} key
   * @returns {boolean}
   */
  has(key) {
    return this._storage.has(key);
  }

  getAll() {
    return this._storage.size > 0 ? objectFromMap(this._storage) : null;
  }

  get size() {
    return this._storage.size;
  }

  setModified() {
    if (!this._modified) {
      this._modified = true;
    }
  }

  resetModified() {
    if (this._modified) {
      this._modified = false;
    }
  }

  /**
   * PLEASE NOTE: Only intended for usage within the API itself.
   * @ignore
   */
  static getHash(map) {
    if (!map) {
      return "";
    }
    const hash = new MurmurHash3_64();

    for (const [key, val] of map) {
      hash.update(`${key}:${JSON.stringify(val)}`);
    }
    return hash.hexdigest();
  }
}

export { PDFAnnotationStorage };
