import { others } from './svg';
import { cells } from './svg';
import { othersFiles, languageSvgStyles, globalSvgStyles } from './western-world.utils.constants';
import {
  getPathByCell,
  getFlagsArray,
  buildImageForCanvasFromHtmlStr,
  getMaskStyles,
} from './western-world.utils.helpers';

const parser = new DOMParser();

// forEach;
export const buildNewSvgImages = ({ allCells, language }) => {
  return Promise.all(
    allCells
      .filter((cell) => cell.id)
      .map((cell) => {
        return Promise.all([
          buildSvgAndImageByHtml({
            name: cell.animatedImage,
            elRequire: cells[cell.animatedImage],
            cell,
            language,
            withMask: true,
          }).then(({ img, svgTag }) => {
            window.cachedImages[language].svgTags[cell.animatedImage] = svgTag;
            window.cachedImages[language].svgTags[cell.id] = svgTag;
            window.cachedImages[language].svgImagesForCanvas[cell.animatedImage] = img;
            window.cachedImages[language].svgImagesForCanvas[cell.id] = img;
          }),
          buildSvgAndImageByHtml({
            name: cell.animatedImage,
            elRequire: cells[cell.animatedImage],
            cell,
            language,
            withMask: false,
            parser,
          }).then(({ img }) => {
            window.cachedImages[language].svgImagesWithoutMasks[cell.animatedImage] = img;
            window.cachedImages[language].svgImagesWithoutMasks[cell.id] = img;
          }),
        ]);
      })
  );
};

export const buildOtherSvgImages = ({ language }) => {
  return Promise.all(
    [...othersFiles, ...getFlagsArray('my'), ...getFlagsArray('enemy')].map((name) => {
      return buildSvgAndImageByHtml({
        name,
        elRequire: others[name],
        cell: null,
        language,
        withMask: false,
      }).then(({ img, svgTag }) => {
        window.cachedImages[language].svgTags[name] = svgTag;
        window.cachedImages[language].svgImagesForCanvas[name] = img;
        window.cachedImages[language].svgImagesWithoutMasks[name] = img;
      });
    })
  );
};

const buildSvgAndImageByHtml = ({ name, elRequire, cell, language, withMask }) => {
  // get svg image from file and apply offsets;
  const doc = parser.parseFromString(elRequire.svg, 'image/svg+xml');
  const svgEl = doc.querySelector('svg');
  svgEl.classList.add(name);

  // create svg style element;
  const styleElement = svgEl.querySelector('svg > style');
  styleElement.insertAdjacentHTML('beforeend', `${globalSvgStyles} ${languageSvgStyles} ${elRequire.css}`);

  // create new <g> and move all content to it to apply mask;
  const gElement = document.createElementNS('http://www.w3.org/2000/svg', 'g');
  gElement.setAttribute('class', language);
  const allSvgImageContent = svgEl.querySelectorAll('svg > *:not(style)');
  [...allSvgImageContent].forEach((el) => gElement.appendChild(el));

  // create defs element;
  const defsElement = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
  defsElement.innerHTML = elRequire.defs ? elRequire.defs.map((el) => el.value).join(' ') : '';

  if (withMask) {
    const cellPath = getPathByCell(name, cell);
    const cellPathSymbol = `<symbol id="path-border-${name}" viewBox="0 0 1 1">${cellPath}</symbol>`
    // TODO probably don't need mask, clipPath would be enough;
    const mask = `
            <mask id="mask-${name}">
              <use xlink:href="#path-border-${name}" class="use-mask"></use>
              <use xlink:href="#additional-mask" class="use-additional-mask"></use>
            </mask>
          `;
    const clipPath = `<clipPath id="clip-path-${name}" clipPathUnits="objectBoundingBox">${cellPath}</clipPath>`;
    gElement.setAttribute('mask', `url(#mask-${name})`);
    styleElement.insertAdjacentHTML('beforeend', getMaskStyles(cell));
    defsElement.insertAdjacentHTML('beforeend', `${cellPathSymbol} ${mask} ${clipPath}`);

    // create use border path;
    const svgUseBorderElement = document.createElementNS('http://www.w3.org/2000/svg', 'use');
    svgUseBorderElement.setAttribute('xlink:href', `#path-border-${name}`);
    svgUseBorderElement.setAttribute('class', 'use-border');
    svgEl.appendChild(svgUseBorderElement);
  }

  svgEl.appendChild(defsElement);
  svgEl.appendChild(gElement);
  return buildImageForCanvasFromHtmlStr(svgEl.outerHTML).then((img) => {
    img.defs = elRequire.defs ? [...elRequire.defs] : null;
    return { svgTag: svgEl.outerHTML, img };
  });
};
