import SocketIO from "socket.io";
import {ResolvedMessageSerialized} from "../api/classes/serialized/resolved-message.serialized";

import {TicketMessagePostToSlackWorkflow} from "../bl/ticket/ticket-message-post-to-slack.workflow";
import {Message} from "../entity/message";
import {Ticket} from "../entity/ticket";
import {TicketEvents} from "./ticket.events";

const SOCKET_TICKET_ID_ATTRIBUTE_NAME = 'ticketId';
const SOCKET_LICENSE_ATTRIBUTE_NAME = 'licenseeId';

interface ISocketData {
  ticketId: number;
  licenseeId: number;
}

export class TicketWs {

  public readonly NAMESPACE_NAME = 'ticket';

  private namespace: SocketIO.Namespace;

  public init(ns: SocketIO.Namespace) {
    console.log('ticket init', ns);
    this.namespace = ns;
    this.addEventListeners();
  }

  private addEventListeners() {
    // this.namespace.use(async (socket, next) => {
    //   // const {ticketId, licenseeId} = this.extractDataFromSocket(socket);
    //   const licenseeId = this.extractLicenseeIdFromSocket(socket);
    //
    //   try {
    //     const tickets = await Ticket.findByIds([ticketId]);
    //     if (tickets.length === 0) {
    //       next(new Error(`Ticket with [id=${ticketId}] not found.`));
    //       return;
    //     }
    //
    //     if (tickets[0].licenseeId != licenseeId) {
    //       next(new Error('License validation error'));
    //       return;
    //     }
    //
    //     next();
    //   } catch (e) {
    //     console.error(e);
    //     next(new Error(e.message));
    //   }
    // });

    this.namespace.on('connection', async socket => {
      // const {ticketId} = this.extractDataFromSocket(socket);
      const licenseeId = this.extractLicenseeIdFromSocket(socket);

      socket.join(licenseeId.toString());
      this.namespace.to(licenseeId.toString()).emit(TicketEvents.CONNECT_SUCCESS);

      socket.on('message', async message => {
        // await TicketMessagePostToSlackWorkflow.messagePosted(ticketId, message);
      });
    });
  }

  private extractLicenseeIdFromSocket(socket: SocketIO.Socket): string {
    return socket.handshake.query[SOCKET_LICENSE_ATTRIBUTE_NAME];
  }

  // private extractDataFromSocket(socket: SocketIO.Socket): ISocketData {
  //   return {
  //     ticketId: parseFloat(socket.handshake.query[SOCKET_TICKET_ID_ATTRIBUTE_NAME]),
  //     licenseeId: parseFloat(socket.handshake.query[SOCKET_LICENSE_ATTRIBUTE_NAME])
  //   };
  // }

  public async postTicketMessage(ticket: Ticket, message: Message) {
    console.log('posting', ticket.id, message.body);
    this.namespace.to(ticket.licenseeId.toString())
      .send(ticket.id, await ResolvedMessageSerialized.createResolvedFromObj(message));
  }

}

export default new TicketWs();
