import App from '../../base'
import ColorManager from '../../ide/colors/ColorManager'
App.controller('TagListController', function ($scope, $modal) {
  $scope.filterProjects = function (filter = 'all') {
    $scope._clearTags()
    $scope.setFilter(filter)
  }

  $scope._clearTags = () =>
    $scope.tags.forEach(tag => {
      tag.selected = false
    })

  $scope.selectTag = function (tag) {
    $scope._clearTags()
    tag.selected = true
    $scope.setFilter('tag')
  }

  $scope.selectUntagged = function () {
    $scope._clearTags()
    $scope.setFilter('untagged')
  }

  $scope.countProjectsForTag = function (tag) {
    return tag.project_ids.reduce((acc, projectId) => {
      const project = $scope.getProjectById(projectId)

      // There is a bug where the tag is not cleaned up when you leave a
      // project, so tag.project_ids can contain a project that the user can
      // no longer access. If the project cannot be found, ignore it
      if (!project) return acc

      // Ignore archived projects as they are not shown in the filter
      if (!(project.archived || project.trashed)) {
        return acc + 1
      } else {
        return acc
      }
    }, 0)
  }

  $scope.getHueForTagId = tagId => ColorManager.getHueForTagId(tagId)

  $scope.deleteTag = function (tag) {
    const modalInstance = $modal.open({
      templateUrl: 'deleteTagModalTemplate',
      controller: 'DeleteTagModalController',
      resolve: {
        tag() {
          return tag
        }
      }
    })
    modalInstance.result.then(function () {
      // Remove tag from projects
      for (let project of $scope.projects) {
        if (!project.tags) {
          project.tags = []
        }
        const index = project.tags.indexOf(tag)
        if (index > -1) {
          project.tags.splice(index, 1)
        }
      }

      // Remove tag in place to update the state everywhere
      $scope.tags.splice($scope.tags.indexOf(tag), 1)
    })
  }

  $scope.renameTag = function (tag) {
    const modalInstance = $modal.open({
      templateUrl: 'renameTagModalTemplate',
      controller: 'RenameTagModalController',
      resolve: {
        tag() {
          return tag
        }
      }
    })
    modalInstance.result.then(newName => (tag.name = newName))
  }
})

App.controller('TagDropdownItemController', function ($scope) {
  $scope.recalculateProjectsInTag = function () {
    let partialSelection
    $scope.areSelectedProjectsInTag = false
    for (let projectId of $scope.getSelectedProjectIds()) {
      if ($scope.tag.project_ids.includes(projectId)) {
        $scope.areSelectedProjectsInTag = true
      } else {
        partialSelection = true
      }
    }

    if ($scope.areSelectedProjectsInTag && partialSelection) {
      $scope.areSelectedProjectsInTag = 'partial'
    }
  }

  $scope.addOrRemoveProjectsFromTag = function () {
    if ($scope.areSelectedProjectsInTag === true) {
      $scope.removeSelectedProjectsFromTag($scope.tag)
      $scope.areSelectedProjectsInTag = false
    } else if (
      $scope.areSelectedProjectsInTag === false ||
      $scope.areSelectedProjectsInTag === 'partial'
    ) {
      $scope.addSelectedProjectsToTag($scope.tag)
      $scope.areSelectedProjectsInTag = true
    }
  }

  $scope.$watch('selectedProjects', () => $scope.recalculateProjectsInTag())
  $scope.recalculateProjectsInTag()
})

App.controller(
  'NewTagModalController',
  function ($scope, $modalInstance, $timeout, $http) {
    $scope.inputs = { newTagName: '' }

    $scope.state = {
      inflight: false,
      error: false
    }

    $modalInstance.opened.then(() =>
      $timeout(() => $scope.$broadcast('open'), 200)
    )

    $scope.create = function () {
      const name = $scope.inputs.newTagName
      $scope.state.inflight = true
      $scope.state.error = false
      $http
        .post('/tag', {
          _csrf: window.csrfToken,
          name
        })
        .then(function (response) {
          const { data } = response
          $scope.state.inflight = false
          $modalInstance.close(data)
        })
        .catch(function () {
          $scope.state.inflight = false
          $scope.state.error = true
        })
    }

    $scope.cancel = () => $modalInstance.dismiss('cancel')
  }
)

App.controller(
  'RenameTagModalController',
  function ($scope, $modalInstance, $timeout, $http, tag) {
    $scope.inputs = { tagName: tag.name }

    $scope.state = {
      inflight: false,
      error: false
    }

    $modalInstance.opened.then(() =>
      $timeout(() => $scope.$broadcast('open'), 200)
    )

    $scope.rename = function () {
      const name = $scope.inputs.tagName
      $scope.state.inflight = true
      $scope.state.error = false
      return $http
        .post(`/tag/${tag._id}/rename`, {
          _csrf: window.csrfToken,
          name
        })
        .then(function () {
          $scope.state.inflight = false
          $modalInstance.close(name)
        })
        .catch(function () {
          $scope.state.inflight = false
          $scope.state.error = true
        })
    }

    $scope.cancel = () => $modalInstance.dismiss('cancel')
  }
)

export default App.controller(
  'DeleteTagModalController',
  function ($scope, $modalInstance, $http, tag) {
    $scope.tag = tag
    $scope.state = {
      inflight: false,
      error: false
    }

    $scope.delete = function () {
      $scope.state.inflight = true
      $scope.state.error = false
      return $http({
        method: 'DELETE',
        url: `/tag/${tag._id}`,
        headers: {
          'X-CSRF-Token': window.csrfToken
        }
      })
        .then(function () {
          $scope.state.inflight = false
          $modalInstance.close()
        })
        .catch(function () {
          $scope.state.inflight = false
          $scope.state.error = true
        })
    }

    $scope.cancel = () => $modalInstance.dismiss('cancel')
  }
)
