import { Action, Module, Mutation, VuexModule } from 'vuex-module-decorators'
import {
  Category,
  CategoryCounting,
  CategoryGroup,
  CategoryGroupCounting,
} from '@/widgets/tasks/types/Category'
import { NotifyHelper } from '@/helpers'
import { Manager } from '@/types/Manager'
import CategoryService from '@/widgets/tasks/http/services/CategoryService'
import WebsocketService from '@/widgets/tasks/http/services/WebsocketService'
import AuthService from '@/widgets/tasks/http/services/AuthService'

@Module({
  name: 'CategoryModule',
  namespaced: true,
})
export class CategoryModule extends VuexModule {
  categories: Category[] = []
  counting: CategoryGroupCounting | null = null
  currentGroup: CategoryGroup = 'today'
  isInitialisedWebsocket = false

  get totalCount(): number {
    if (!this.counting) {
      return 0
    }

    return Object.values(this.counting).reduce((total, group) => {
      return total + group.allCount
    }, 0)
  }

  get getCountTaskForCategory() {
    return (group: CategoryGroup, categoryId: number) => {
      if (!this.counting) {
        return 0
      }

      const counting = this.counting[group].groupCount.find(
        c => c.id === categoryId
      ) as CategoryCounting

      return counting ? counting.taskCount : 0
    }
  }

  @Mutation
  setInitializeWebsocket() {
    this.isInitialisedWebsocket = true
  }

  get getCountTasksForGroup() {
    return (group: CategoryGroup) =>
      this.counting ? this.counting[group].allCount : 0
  }

  get getGroupTitle() {
    return (groupName: CategoryGroup) =>
      this.counting ? this.counting[groupName].title : ''
  }

  get getCategoryById() {
    return (categoryId: number) =>
      this.categories.find(category => category.id === categoryId)
  }

  @Mutation
  setCurrentGroup(group: CategoryGroup) {
    this.currentGroup = group
  }

  @Mutation
  setCategories(categories: Category[]) {
    this.categories = categories
  }

  @Mutation
  setCounting(counting: CategoryGroupCounting) {
    this.counting = counting
  }

  @Action
  loadCategories() {
    return CategoryService.loadCategories()
      .then(categories => this.setCategories(categories))
      .catch(() => NotifyHelper.error('Ошибка загрузки категорий'))
  }

  @Action
  loadCounting() {
    return CategoryService.loadCounting().then(counting =>
      this.setCounting(counting)
    )
  }

  @Action
  async initWebsocket(user: Manager) {
    if (this.isInitialisedWebsocket) {
      return
    }

    this.setInitializeWebsocket()

    try {
      const token = await AuthService.getAuthToken()

      WebsocketService.init(token, user)

      WebsocketService.onUpdateCounting(payload => {
        this.setCounting(payload.categories)
      })
    } catch (e) {
      NotifyHelper.error('Ошибка подключения к сокетам')
    }
  }
}
