import template from './ws-content-selector.tmpl.html';

ContentSelectorDirective.$inject = ['$sce', '$filter'];

export default function ContentSelectorDirective($sce, $filter) {
  return {
    restrict: 'E',
    template,
    scope: {
      options: '<',
      type: '@',
      rowSize: '@',
      selected: '=',
      stacked: '<',
      expandable: '<',
    },
    link($scope) {
      const validTypes = ['single', 'multi'];

      const hoverColour = '#FDFCF9';

      if (!$scope.type) {
        $scope.type = 'single';
      }

      $scope.optionMetaData = [];

      if (validTypes.indexOf($scope.type) === -1) {
        throw new Error('invalid type set on wsContentSelector');
      }

      if (!$scope.selected && $scope.type === 'multi') {
        $scope.selected = [];
      }

      if (!$scope.rowSize) {
        $scope.rowSize = 4;
      }

      if (!$scope.stacked) {
        $scope.stacked = false;
      } else if ($scope.stacked === true) {
        $scope.rowSize = 1;
      }

      $scope.colSize = Math.floor(12 / $scope.rowSize);

      $scope.$watchCollection('options', _rebuildInternalRepresentations);

      $scope.select = (selectedOption) => {
        if (selectedOption.disabled) {
          return;
        }

        if ($scope.type === 'multi') {
          const index = $scope.selected.indexOf(selectedOption);

          if (index === -1) {
            $scope.selected.push(selectedOption);
          } else {
            $scope.selected.splice(index, 1);
          }
        } else {
          $scope.selected = selectedOption;
        }
      };

      $scope.isSelected = (option) => {
        if ($scope.type === 'multi') {
          return $scope.selected.indexOf(option) !== -1;
        }

        return $scope.selected === option;
      };

      $scope.showMoreInfo = ($event, option) => {
        $event.stopPropagation();
        const metaData = $scope.getMetaData(option);
        metaData.moreInfo = !metaData.moreInfo;
      };

      $scope.mouseEnter = (option) => {
        $scope.getMetaData(option).hoveredOptions = {
          'background-color': hoverColour,
          'border-left': `2px solid ${option.color ? option.color : '#fab131'}`,
        };
      };

      $scope.mouseLeave = (option) => {
        $scope.getMetaData(option).hoveredOptions = {};
      };

      $scope.getBufferRow = row => new Array($scope.rowSize - row.length);

      $scope.getOptionStyle = (option) => {
        if ($scope.isSelected(option) && option.color) {
          return {
            'background-color': option.color,
            color: option.color,
          };
        } else if (!$scope.isSelected(option)) {
          return $scope.getMetaData(option).hoveredOptions;
        }

        return '';
      };

      $scope.getMetaData = (option) => {
        const idx = $scope.options.indexOf(option);
        return $scope.optionMetaData[idx];
      };

      function _rebuildInternalRepresentations() {
        $scope.optionMetaData = _buildOptionMetaData();
        $scope.chunkedOptions = _buildChunkedOptions();
      }

      function _buildOptionMetaData() {
        return $scope.options.map(option => ({
          trustedBody: $sce.trustAsHtml(option.body),
          trustedBlurb: $sce.trustAsHtml(option.blurb),
        }));
      }

      function _buildChunkedOptions() {
        return $filter('chunk')($scope.options, $scope.rowSize);
      }
    },
  };
}
