import {
  ProtocolRequest,
  ProtocolResponse,
  ProtocolEncoder,
  PacketBody,
  ProtocolDecoder,
  ProtocolMessage,
  ProtocolStream,
  PacketBodyValue,
  BodyStringDivider,
  decodeProtocolMessage
} from '@ucap-webmessenger/protocol';
import { EventType } from '../types/event.type';
import { Info } from '../models/info';
import { decodeEventJson, EventJson } from './event-json/codec';

export interface InfoRequest extends ProtocolRequest {
  // 대화방SEQ(s)
  roomSeq: string;
  // 기준이벤트SEQ(n)
  baseSeq: number;
  // 요청이벤트개수(n)
  requestCount: number;
}

export interface InfoData extends ProtocolStream {
  // 대화방SEQ(s)
  roomSeq: string;
  infoList: Info<EventJson>[];
}

export interface InfoResponse extends ProtocolResponse {
  // 대화방SEQ(s)
  roomSeq: string;
  // 기준이벤트SEQ(n)
  baseSeq: number;
  // 유효한파일기준이벤트SEQ(n)
  validFileBaseSeq: number;
}

export const encodeInfo: ProtocolEncoder<InfoRequest> = (req: InfoRequest) => {
  const bodyList: PacketBody[] = [];

  bodyList.push(
    { type: PacketBodyValue.String, value: req.roomSeq },
    { type: PacketBodyValue.Integer, value: req.baseSeq },
    { type: PacketBodyValue.Integer, value: req.requestCount }
  );

  return bodyList;
};

export const decodeInfoData: ProtocolDecoder<InfoData> = (
  message: ProtocolMessage
) => {
  const infoList: Info<EventJson>[] = [];

  for (const body of message.bodyList) {
    const info = body.split(BodyStringDivider);
    if (info.length > 5) {
      const eventType = info[1] as EventType;

      infoList.push({
        seq: Number(info[0]),
        type: eventType,
        senderSeq: Number(info[2]),
        sendDate: info[3],
        sentMessage: info[4],
        sentMessageJson: decodeEventJson(eventType, info[4]),
        receiverCount: Number(info[5])
      });
    }
  }

  return decodeProtocolMessage(message, {
    roomSeq: message.bodyList[0],
    infoList
  } as InfoData);
};

export const decodeInfo: ProtocolDecoder<InfoResponse> = (
  message: ProtocolMessage
) => {
  return decodeProtocolMessage(message, {
    roomSeq: message.bodyList[0],
    baseSeq: message.bodyList[1],
    validFileBaseSeq: message.bodyList[2]
  } as InfoResponse);
};
