import {
  QueueItemModel,
  QueueModel,
  QueueTicketModel,
} from '../../../data/models/queue.model';
import { MergedItemQueue } from '../../entities/queue-item.entity';
import { toTime } from '../../helpers/time.helper';

export class CustomerQueueManager {
  constructor(protected readonly tickets: QueueTicketModel[]) {}
  get data(): any {
    return this.tickets;
  }

  toTime(timestamp: number): string {
    return toTime(timestamp);
  }

  totalActivities(ticket: QueueTicketModel): number {
    const ticketItems = {};
    ticket.items.forEach((item) => {
      const item_id =
        item.item?.item_queue?.id ?? item.item?.id ?? item.item_id;
      const currentItem = ticketItems[item_id];
      ticketItems[item_id] = currentItem ? [...currentItem, item] : [item];
    });
    return Object.keys(ticketItems).length;
  }

  totalTickets(ticket: QueueTicketModel): number {
    return ticket.items.reduce((acc, item) => acc + item.qty, 0);
  }

  totalUsedItems(queues: QueueModel[]): number {
    return queues
      .filter((q) => ['done', 'called'].includes(q.status))
      .reduce((acc, item) => acc + item.qty, 0);
  }

  totalUsedTickets(ticket: QueueTicketModel): number {
    const tickets = ticket.items.map((item) => {
      return this.totalUsedItems(item.queue);
    });

    const reducer = (accumulator, currentValue) => accumulator + currentValue;
    return tickets.reduce(reducer, 0);
  }

  totalQueueItems(queues: QueueModel[]): number {
    return queues
      .filter((q) => ['waiting'].includes(q.status))
      .reduce((acc, item) => acc + item.qty, 0);
  }

  totalQueueTickets(ticket: QueueTicketModel): number {
    const tickets = ticket.items.map((item) => {
      return this.totalQueueItems(item.queue);
    });

    const reducer = (accumulator, currentValue) => accumulator + currentValue;
    return tickets.reduce(reducer, 0);
  }

  totalQueueItemTickets(ticket: QueueTicketModel): number {
    const tickets = ticket.items
      .map((item) => {
        return this.totalQueueItems(item.queue);
      })
      .filter((item) => item > 0);

    return tickets.length;
  }

  summaryTicket(ticket: QueueTicketModel): any {
    const total_tickets = this.totalTickets(ticket);
    const total_used = this.totalUsedTickets(ticket);
    const total_queue = this.totalQueueTickets(ticket);
    const total_queue_item = this.totalQueueItemTickets(ticket);
    return {
      total_activities: this.totalActivities(ticket),
      total_tickets,
      total_used,
      total_queue,
      total_queue_item,
      remaining: total_tickets - total_queue,
    };
  }

  mergeQueueItems(ticket: QueueTicketModel): MergedItemQueue[] {
    const ticketItems = {};
    ticket.items.forEach((item) => {
      const item_id = item.item.item_queue?.id ?? item.item.id;
      const currentItem = ticketItems[item_id];
      ticketItems[item_id] = currentItem ? [...currentItem, item] : [item];
    });

    return Object.values<QueueItemModel[]>(ticketItems).map((items) => {
      const item = items[0];
      const queues: QueueModel[] = [];

      items.forEach((item) => {
        queues.push(...item.queue);
      });

      const item_qty = items.reduce((acc, item) => acc + item.qty, 0);
      const queueItem = item.item.item_queue ?? item.item;
      return {
        id: item.item_id,
        queue_item_id: queueItem.id,
        item_id: item.id,
        title: queueItem.name,
        image_url: item.item.image_url,
        qty: item_qty,
        queues,
      };
    });
  }
}
