import {
  ProtocolRequest,
  ProtocolResponse,
  ProtocolEncoder,
  PacketBody,
  ProtocolDecoder,
  ProtocolMessage,
  ProtocolStream,
  PacketBodyValue
} from '@ucap-webmessenger/protocol';
import { EventType } from '../types/event.type';

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

export interface Info {
  // 이벤트SEQ
  seq: number;
  // 이벤트타입
  type: EventType;
  // 발신자SEQ
  senderSeq: number;
  // 발신일시
  sendDate: Date;
  // 발신내용
  sentMessage: string;
  // 수신자수
  receiverCount: number;
}

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

export interface InfoResponse extends ProtocolResponse {
  // 대화방SEQ(s)
  roomSeq: string;
  // 기준이벤트SEQ(n)
  baseSeq: number;
  // 유효한파일기준이벤트SEQ(n)
  validFileBaseSeq: number;
  // 이벤트정보 개수(n)
  count: 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[] = [];
  for (let i = 1; i < message.bodyList.length; ) {
    infoList.push({
      seq: message.bodyList[i++],
      type: message.bodyList[i++],
      senderSeq: message.bodyList[i++],
      sendDate: message.bodyList[i++],
      sentMessage: message.bodyList[i++],
      receiverCount: message.bodyList[i++]
    });
  }

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

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