class FlatCube extends HTMLElement {

  constructor() {
    super();

    this.faces = 'URFDLB'.split('');

    this.facelet = false;

    // We attach an open shadow root to the custom element
    this._shadowRoot = this.attachShadow({ mode: 'open' });

    this.template = this.createTemplate();

    this.render();
  }

  style() {
    return `
:host {
  display: inline-block;
  --flat-cube-face-width: var(--flat-cube-face, 100px);
}
.flat-cube {
  position: relative;
  height: calc(3 * var(--flat-cube-face-width));
  margin: 0 auto;
  width: calc(4 * var(--flat-cube-face-width));
}
.face {
  display: flex;
  height: var(--flat-cube-face-width);
  width: var(--flat-cube-face-width);
  outline: 1px solid var(--flat-cube-outer, black);
  position: absolute;
  flex-wrap: wrap;
  justify-content: space-between;
}
.U-face {top:0; left: var(--flat-cube-face-width); }
.L-face {top:var(--flat-cube-face-width); left: 0; }
.F-face {top:var(--flat-cube-face-width); left: var(--flat-cube-face-width); }
.R-face {top:var(--flat-cube-face-width); left: calc(2 * var(--flat-cube-face-width)); }
.B-face {top:var(--flat-cube-face-width); left: calc(3 * var(--flat-cube-face-width)); }
.D-face {top:calc(2 * var(--flat-cube-face-width)); left: var(--flat-cube-face-width); }
.face > div {
  width: calc(var(--flat-cube-face-width)/3);
  height: calc(var(--flat-cube-face-width)/3);
  outline: 1px solid var(--flat-cube-inner, black);
}
.U-piece {background-color: var(--flat-cube-up,    #ebed2b); }
.L-piece {background-color: var(--flat-cube-left,  #ff6b16); }
.F-piece {background-color: var(--flat-cube-front, #6cfe3b); }
.R-piece {background-color: var(--flat-cube-right, #ec1d35); }
.B-piece {background-color: var(--flat-cube-back,  #4db4d7); }
.D-piece {background-color: var(--flat-cube-down,  #fffbf8); }
`;
  }

  createTemplate() {
    const template = document.createElement('template');
    template.innerHTML = `<style>${this.style()}</style>`;
    const cubeElement = document.createElement('div');
    cubeElement.classList.add('flat-cube');
    this.faces.forEach((face, i) => {
      const faceElement = document.createElement('div');
      faceElement.classList.add('face');
      faceElement.classList.add(`${face}-face`);
      for (let j=0; j < 9; j++) {
        faceElement.appendChild(this.preparePiece(i, j));
      }
      cubeElement.appendChild(faceElement);
    });
    template.content.appendChild(cubeElement);
    return template;
  }

  updateTemplate() {
    const update = this.template.content.cloneNode(true);
    update.querySelectorAll('.face').forEach((face, i) => {
      face.querySelectorAll('div').forEach((piece, j) => {
        this.preparePiece(i, j, piece);
      });
    });
    return update;
  }

  preparePiece(i, j, piece = document.createElement('div')) {
    const start = (i * 9) + j;
    const end = (i * 9) + j + 1;
    piece.className = !this.facelet ? `${this.faces[i]}-piece` : `${this.facelet.slice(start, end)}-piece`;
    return piece;
  }

  render() {
    this._shadowRoot.innerHTML = '';
    this._shadowRoot.appendChild(this.updateTemplate());
  }

  static get observedAttributes() {
    return ['facelet'];
  }

  attributeChangedCallback(name, oldValue, newValue) {
    this.facelet = newValue;
    this.render();
  }
}

if (!window.customElements.get('flat-cube')) {
  customElements.define('flat-cube', FlatCube);
}