import {
  ProtocolRequest,
  ProtocolResponse,
  ProtocolEncoder,
  PacketBody,
  PacketBodyValue,
  ProtocolDecoder,
  ProtocolMessage,
  BodyStringDivider,
  ProtocolStream,
  decodeProtocolMessage
} from '@ucap-webmessenger/protocol';
import { FileType } from '../types/file.type';
import { FileInfo } from '../models/file-info';
import { FileDownloadInfo } from '../models/file-download-info';
import {
  decodeEventJson,
  EventType,
  FileEventJson
} from '@ucap-webmessenger/protocol-event';

export interface InfoRequest extends ProtocolRequest {
  // 대화방SEQ(s)
  roomSeq: string;
  // { 파일타입 } cf) I : 이미지 V: 동영상 F: 파일 "" 빈값이면 모든 타입을 내려줌
  type: FileType;
}

export interface InfoData extends ProtocolStream {
  // { 대화방파일정보 }...
  fileInfos: FileInfo[];
}

export interface InfoCheckData extends ProtocolStream {
  // { 파일다운로드정보 }...
  fileDownloadInfos: FileDownloadInfo[];
}

export interface InfoResponse extends ProtocolResponse {
  // 대화방SEQ(s)
  roomSeq: string;
  // { 파일타입 } cf) I : 이미지 V: 동영상 F: 파일 "" 빈값이면 모든 타입을 내려줌
  type: FileType;
}

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

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

export const decodeInfoData: ProtocolDecoder<InfoData> = (
  message: ProtocolMessage
) => {
  const fileInfos: FileInfo[] = [];
  message.bodyList.forEach(fileInfo => {
    const info = fileInfo.split(BodyStringDivider);
    fileInfos.push({
      roomSeq: info[0],
      eventSeq: Number(info[1]),
      seq: Number(info[2]),
      senderSeq: Number(info[3]),
      type: info[4] as FileType,
      name: info[5],
      url: info[6],
      size: info[7],
      sendDate: info[8],
      receivedUserCount: Number(info[9]),
      receiverCount: Number(info[10]),
      sentMessage: info[11],
      sentMessageJson: decodeEventJson(
        EventType.File,
        info[11]
      ) as FileEventJson
    });
  });

  return decodeProtocolMessage(message, {
    fileInfos
  } as InfoData);
};

export const decodeInfoCheckData: ProtocolDecoder<InfoCheckData> = (
  message: ProtocolMessage
) => {
  const fileDownloadInfos: FileDownloadInfo[] = [];
  message.bodyList.forEach(fileInfo => {
    const info = fileInfo.split(BodyStringDivider);
    fileDownloadInfos.push({
      roomSeq: info[0],
      seq: Number(info[1]),
      userSeq: Number(info[2]),
      userName: info[3],
      downloadDate: info[4],
      isDownload: info[5] === 'Y' ? true : false
    });
  });

  return decodeProtocolMessage(message, {
    fileDownloadInfos
  } as InfoCheckData);
};

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