import * as $ from 'jquery';
import * as _ from 'lodash';

export interface IXosComponentInjectorService {
  injectedComponents: IXosInjectedComponent[];
  injectComponent(target: string | JQuery, componentName: string, attributes?: any, transclude?: string, clean?: boolean): void;
  removeInjectedComponents(target: string | JQuery): void;
}

export interface IXosInjectedComponent {
  targetEl: string;
  componentName: string;
  attributes?: any;
  transclude?: string;
  clean?: boolean;
}

export class XosComponentInjector implements IXosComponentInjectorService {
  static $inject = ['$rootScope', '$compile', '$transitions', '$log', '$timeout'];

  public injectedComponents: IXosInjectedComponent[] = [];

  constructor (
    private $rootScope: ng.IRootScopeService,
    private $compile: ng.ICompileService,
    private $transitions: any,
    private $log: ng.ILogService,
    private $timeout: ng.ITimeoutService
  ) {
    $transitions.onFinish({ to: '**' }, (transtion) => {
      // wait for route transition to complete
      transtion.promise.then(t => {
        _.forEach(this.injectedComponents, (component: IXosInjectedComponent) => {
          const container = $(component.targetEl);
          // if we have the container, re-attach the component
          if (container.length > 0) {
            this.injectComponent(
              container,
              component.componentName,
              component.attributes,
              component.transclude,
              component.clean
            );
          }
        });
      });
    });
  }

  public injectComponent(target: string | JQuery, componentName: string, attributes?: any, transclude?: string, clean?: boolean) {
    let targetEl;
    if (angular.isString(target)) {

      if (target.indexOf('#') === -1) {
        this.$log.warn(`[XosComponentInjector] Target element should be identified by an ID, you passed: ${target}`);
      }

      targetEl = $(target);
    }
    else {
      targetEl = target;
    }

    const componentTagName = this.camelToSnakeCase(componentName);
    let scope = this.$rootScope.$new();
    let attr: string = '';

    if (clean) {
      this.removeInjectedComponents(target);
    }

    if (angular.isDefined(attributes) && angular.isObject(attributes)) {
      attr = this.stringifyAttributes(attributes);
      // we cannot use angular.merge as it cast Resource to Objects
      _.forEach(Object.keys(attributes), (k: string) => {
        scope[k] = attributes[k];
      });
    }

    const componentTag = `<${componentTagName} ${attr}>${transclude || ''}</${componentTagName}>`;
    const element = this.$compile(componentTag)(scope);

    this.$timeout(function() {
      scope.$apply();
    });

    targetEl.append(element);

    // store a reference for the element
    this.storeInjectedComponent({
      targetEl: angular.isString(target) ? target : '#' + targetEl.attr('id'),
      componentName: componentName,
      attributes: attributes,
      transclude: transclude,
      clean: clean,
    });
  }

  public removeInjectedComponents(target: string | JQuery) {
    const targetEl = $(target);
    targetEl.html('');
  }

  private isComponendStored(component: IXosInjectedComponent) {
    return _.find(this.injectedComponents, (c: IXosInjectedComponent) => {
      return c.targetEl === component.targetEl
        && c.componentName === component.componentName
        && _.isEqual(c.attributes, component.attributes)
        && c.transclude === component.transclude
        && c.clean === component.clean;
    });
  }

  private storeInjectedComponent(component: IXosInjectedComponent) {
    const isAlreadyStored = this.isComponendStored(component);
    if (!isAlreadyStored) {
      this.injectedComponents.push(component);
    }
  }

  private stringifyAttributes(attributes: any): string {
    return _.reduce(Object.keys(attributes), (string: string, a: string) => {
      string += `${this.camelToSnakeCase(a)}="${a}"`;
      return string;
    }, '');
  }

  private camelToSnakeCase(name: string): string {
    return name.split(/(?=[A-Z])/).map(w => w.toLowerCase()).join('-');
  };
}
