import { getWindow, getDocument } from 'ssr-window';
import Template7 from 'template7';
import $ from '../../shared/dom7';
import { id } from '../../shared/utils';

function parseComponent(componentString) {
  var window = getWindow();
  var document = getDocument();
  var componentId = id();
  var callbackCreateName = "f7_component_create_callback_" + componentId;
  var callbackRenderName = "f7_component_render_callback_" + componentId; // Template

  var template;
  var hasTemplate = componentString.match(/<template([ ]?)([a-z0-9-]*)>/);
  var templateType = hasTemplate[2] || 't7';

  if (hasTemplate) {
    template = componentString.split(/<template[ ]?[a-z0-9-]*>/).filter(function (item, index) {
      return index > 0;
    }).join('<template>').split('</template>').filter(function (item, index, arr) {
      return index < arr.length - 1;
    }).join('</template>').replace(/{{#raw}}([ \n]*)<template/g, '{{#raw}}<template').replace(/\/template>([ \n]*){{\/raw}}/g, '/template>{{/raw}}').replace(/([ \n])<template/g, '$1{{#raw}}<template').replace(/\/template>([ \n])/g, '/template>{{/raw}}$1');
  } // Parse Styles


  var style = null;
  var styleScoped = false;

  if (componentString.indexOf('<style>') >= 0) {
    style = componentString.split('<style>')[1].split('</style>')[0];
  } else if (componentString.indexOf('<style scoped>') >= 0) {
    styleScoped = true;
    style = componentString.split('<style scoped>')[1].split('</style>')[0];
    style = style.replace(/{{this}}/g, "[data-f7-" + componentId + "]").replace(/[\n]?([^{^}]*){/gi, function (string, rules) {
      if (rules.indexOf('"') >= 0 || rules.indexOf("'") >= 0) return string; // eslint-disable-next-line

      rules = rules.split(',').map(function (rule) {
        if (rule.indexOf('@') >= 0) return rule;
        if (rule.indexOf("[data-f7-" + componentId + "]") >= 0) return rule;
        return "[data-f7-" + componentId + "] " + rule.trim();
      }).join(', ');
      return "\n" + rules + " {";
    });
  } // Parse Script


  var scriptContent;
  var scriptEl;

  if (componentString.indexOf('<script>') >= 0) {
    var scripts = componentString.split('<script>');
    scriptContent = scripts[scripts.length - 1].split('</script>')[0].trim();
  } else {
    scriptContent = 'return {}';
  }

  if (!scriptContent || !scriptContent.trim()) scriptContent = 'return {}';
  scriptContent = "window." + callbackCreateName + " = function () {" + scriptContent + "}"; // Insert Script El

  scriptEl = document.createElement('script');
  scriptEl.innerHTML = scriptContent;
  $('head').append(scriptEl);
  var component = window[callbackCreateName]();
  var isClassComponent = typeof component === 'function'; // Remove Script El

  $(scriptEl).remove();
  window[callbackCreateName] = null;
  delete window[callbackCreateName]; // Assign Template

  if (!component.template && !component.render) {
    component.template = template;
    component.templateType = templateType;
  }

  if (component.template) {
    if (component.templateType === 't7') {
      if (isClassComponent) {
        var templateFunction = Template7.compile(component.template);

        component.prototype.render = function render() {
          return templateFunction(this);
        };
      } else {
        component.template = Template7.compile(component.template);
      }
    }

    if (component.templateType === 'es') {
      var renderContent = "window." + callbackRenderName + " = function () {\n        return function render() {\n          return `" + component.template + "`;\n        }\n      }";
      scriptEl = document.createElement('script');
      scriptEl.innerHTML = renderContent;
      $('head').append(scriptEl);

      if (isClassComponent) {
        component.prototype.render = component.template;
      } else {
        component.render = window[callbackRenderName]();
      } // Remove Script El


      $(scriptEl).remove();
      window[callbackRenderName] = null;
      delete window[callbackRenderName];
    }
  }

  if (isClassComponent) {
    delete component.template;
    delete component.templateType;
  } // Assign Style


  if (style) {
    component.style = style;
    component.styleScoped = styleScoped;
  } // Component ID


  component.id = componentId;
  return component;
}

export default parseComponent;