import { Injectable } from '@nestjs/common';
import { QueueDataService, QueueService } from '../data/services/queue.service';
import { IndexQueueManager } from './usecases/index-queue.manager';
import { PaginationResponse } from 'src/core/response/domain/ok-response.interface';
import { Queue } from './entities/queue.entity';
import { TABLE_NAME } from 'src/core/strings/constants/table.constants';
import {
  CallQueueManager,
  DoneQueueManager,
} from './usecases/call-queue.manager';
import {
  ORDER_TYPE,
  QUEUE_STATUS,
} from 'src/core/strings/constants/base.constants';
import { QueueTimeFormula } from './usecases/formula/queue-time.formula';
import * as moment from 'moment';
import { timeIsBefore } from './helpers/time.helper';
import { WhatsappService } from 'src/services/whatsapp/whatsapp.service';
import { WhatsappQueue } from 'src/services/whatsapp/entity/whatsapp-queue.entity';

@Injectable()
export class QueueAdminOrchestrator {
  constructor(
    private readonly dataService: QueueDataService,
    private readonly service: QueueService,
    private indexManager: IndexQueueManager,
    private callManager: CallQueueManager,
    private doneManager: DoneQueueManager,
    private readonly queueTimeFormula: QueueTimeFormula,
  ) {}

  async index(params): Promise<PaginationResponse<Queue>> {
    this.indexManager.setFilterParam({ order_type: ORDER_TYPE.ASC, ...params });
    this.indexManager.setService(this.dataService, TABLE_NAME.QUEUE);
    await this.indexManager.execute();
    return this.indexManager.getResult();
  }

  async call(dataId): Promise<string> {
    this.callManager.setData(dataId, QUEUE_STATUS.CALLED);
    this.callManager.setService(this.service, TABLE_NAME.QUEUE);
    await this.callManager.execute();
    return this.callManager.getResult();
  }

  async done(dataId): Promise<string> {
    this.doneManager.setData(dataId, QUEUE_STATUS.DONE);
    this.doneManager.setService(this.service, TABLE_NAME.QUEUE);
    await this.doneManager.execute();
    return this.doneManager.getResult();
  }

  async job(): Promise<void> {
    const notification = new WhatsappService();
    const itemMasters = await this.dataService.allQueue();
    const currentTime = moment().valueOf();

    for (const queueItem of itemMasters) {
      const queueTimes = await this.queueTimeFormula.items(queueItem.id);
      const call_preparation = queueItem.call_preparation * 60 * 1000;
      if (!queueItem.use_notification) continue;

      for (const queueId in queueTimes) {
        const callTime = queueTimes[queueId];

        const queueTicket = await this.service.queueTicket(queueId);
        if (
          queueItem.requiring_notification ||
          (timeIsBefore(currentTime, callTime, call_preparation) &&
            queueTicket.time > currentTime)
        ) {
          const payload: WhatsappQueue = {
            id: queueId,
            phone: queueTicket.item.ticket.phone,
            code: queueTicket.code,
            name: queueTicket.item.ticket.customer,
            item_name: queueItem.name,
            time: callTime,
          };

          // console.table([
          //   {
          //     code: queueTicket.code,
          //     currentTime: toTime(currentTime),
          //     callTime: toTime(callTime),
          //     lastNotification: toTime(queueTicket.last_notification),
          //   },
          // ]);

          if (
            queueTicket.item.ticket.phone != null &&
            queueTicket.last_notification < currentTime - call_preparation
          ) {
            await notification.queueProcess(payload);
            this.service.updateLastNotification(queueId, currentTime);
          }
        }
      }
    }
  }
}
