import {TOOL_INFO_CLASSNAME, WIDE_CLASSNAME} from '../config.js';
import {hash} from '../helper.js';
import {Tool} from '../tool.js';

export class StateTool extends Tool {
  stored = [];

  async setContainer(container) {
    super.setContainer(container);

    const buttons = document.createElement('div');
    const save = document.createElement('button');
    const list = document.createElement('div');

    save.innerHTML = 'Save';

    save.classList.add(WIDE_CLASSNAME);
    buttons.style.display = 'flex';
    buttons.style.flexDirection = 'row';
    buttons.appendChild(save);
    list.style.display = 'flex';
    list.style.flexDirection = 'column';
    this.div.appendChild(buttons);
    this.div.appendChild(list);

    save.addEventListener('click', async () => {
      const state = this.sim.toJSON();
      this.stored.push(state);
      const item = await this.createItem(state);
      list.appendChild(item);
    });

    // Check url query parameter, and load specified state if found
    await this.fromUrl();
  }

  async toUrl(state) {
    const stateText = JSON.stringify(state);
    const digest = await hash(stateText);
    const rawUrl = `./?state=${stateText}&digest=${digest}`;
    const url = encodeURI(rawUrl);
    return {url, digest};
  }

  async fromUrl() {
    const paramsString = window.location.search;
    const searchParams = new URLSearchParams(paramsString);
    const stateEnc = searchParams.get("state");
    const rxDigest = searchParams.get("digest");
    if (stateEnc) {
      const stateText = decodeURI(stateEnc);
      console.log('decoded state text', stateText);
      const state = JSON.parse(stateText);
      const digest = await hash(stateText);
      if (digest !== rxDigest) {
        throw new Error('state query parameter does not match digest query parameter');
      }
      // Tools in this system can be very powerful
      this.sim.fromJSON(state);
    }
  }

  getStateDescription(state) {
    const date = new Date(state.dateSaved);
    const Y = date.getFullYear().toString();
    const M = (date.getMonth() + 1).toString().padStart(2, '0');
    const D = date.getDate().toString().padStart(2, '0');
    const h = date.getHours().toString().padStart(2, '0');
    const m = date.getMinutes().toString().padStart(2, '0');
    const s = date.getSeconds().toString().padStart(2, '0');
    return `${Y}-${M}-${D} ${h}:${m}:${s}`;
  }

  async createItem(state) {
    const item = document.createElement('div');
    item.style.display = 'flex';
    item.style.flexDirection = 'row';
    item.style.flexWrap = 'wrap';

    const description = document.createElement('button');
    description.style.flex = '2';
    description.classList.add(TOOL_INFO_CLASSNAME);
    description.innerHTML = this.getStateDescription(state);

    const load = document.createElement('button');
    load.style.flex = '1';

    const link = document.createElement('a');
    const {url, digest} = await this.toUrl(state);
    link.href = url;
    link.innerHTML = digest.slice(0, 5);

    load.appendChild(link);

    item.appendChild(description);
    item.appendChild(load);

    load.addEventListener('click', (e) => {
      e.preventDefault();
      // Tools in this system can wield great power
      this.sim.fromJSON(state);
    });

    return item;
  }
}
