import io from 'socket.io-client'
import Echo from 'laravel-echo'
import { Task } from '@/widgets/tasks/types/Task'
import { CategoryGroupCounting } from '@/widgets/tasks/types/Category'
import { Manager } from '@/types/Manager'

export type onCreateTask = (payload: { task: Task }) => void
export type onUpdateTask = (payload: { task: Task }) => void
export type onDeleteTask = (payload: { task: Task }) => void
export type onUpdateCounting = (payload: {
  categories: CategoryGroupCounting
}) => void

export enum Events {
  updateTask = 'TaskUpdated',
  createTask = 'TaskCreated',
  deleteTask = 'TaskDeleted',
  updateCounting = 'CategoriesGroupUpdate',
}

window.io = io

class WebsocketService {
  client!: Echo
  user!: Manager

  init(bearerToken: string, user: Manager) {
    if (this.client) {
      return
    }

    this.user = user
    this.client = new Echo({
      broadcaster: 'socket.io',
      key: 'random',
      cluster: 'mt1',
      host: process.env.TASKS_WS_URL,
      transports: ['websocket', 'polling', 'flashsocket'],
      auth: {
        headers: {
          Authorization: 'Bearer ' + bearerToken,
          host: location.hostname,
        },
      },
    })
  }

  public onCreateTask(cb: onCreateTask) {
    this.getBroadcastChannel().listen(Events.createTask, cb)
  }

  public onUpdateTask(cb: onUpdateTask) {
    this.getBroadcastChannel().listen(Events.updateTask, cb)
  }

  public onDeleteTask(cb: onDeleteTask) {
    this.getBroadcastChannel().listen(Events.deleteTask, cb)
  }

  public onUpdateCounting(cb: onUpdateCounting) {
    this.getBroadcastChannel().listen(Events.updateCounting, cb)
  }
  private getBroadcastChannel() {
    return this.client.private(`Tasks.${this.user.id}`)
  }
}

export default new WebsocketService()
