import {
  ProtocolRequest,
  ProtocolResponse,
  ProtocolEncoder,
  PacketBody,
  PacketBodyValue,
  ProtocolDecoder,
  ProtocolMessage,
  BodyStringDivider,
  ProtocolNotification,
  decodeProtocolMessage
} from '@ucap-webmessenger/protocol';
import { RoomExitType } from '../types/room.type';

export interface ExitRequest extends ProtocolRequest {
  // 대화방SEQ(s)
  roomSeq: string;
}

export interface ExitResponse extends ProtocolResponse {
  // 대화방SEQ(s)
  roomSeq: string;
}

export interface ExitNotification extends ProtocolNotification {
  // 대화방SEQ(s)
  roomSeq: string;
}

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

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

export const decodeExit: ProtocolDecoder<ExitResponse> = (
  message: ProtocolMessage
) => {
  return decodeProtocolMessage(message, {
    roomSeq: message.bodyList[0]
  } as ExitResponse);
};
export const decodeExitNotification: ProtocolDecoder<ExitNotification> = (
  message: ProtocolMessage
) => {
  return decodeProtocolMessage(message, {
    roomSeq: message.bodyList[0]
  } as ExitNotification);
};

export interface ExitAllRequest extends ProtocolRequest {
  // 대화방SEQ(s)
  roomSeq: string[];
}
export interface ExitAllResponse extends ProtocolResponse {
  // 대화방SEQ(s)
  roomSeq: string[];
}

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

  bodyList.push({ type: PacketBodyValue.String, value: req.roomSeq.join(',') });
  return bodyList;
};
export const decodeAllExit: ProtocolDecoder<ExitAllResponse> = (
  message: ProtocolMessage
) => {
  return decodeProtocolMessage(message, {
    roomSeq: message.bodyList[0].split(BodyStringDivider)
  } as ExitAllResponse);
};

export interface ExitForcingRequest extends ProtocolRequest {
  // 대화방SEQ(s)
  roomSeq: string;
  // 강퇴요청타입(s)
  type: string;
  // sender사용자SEQ(n)
  senderSeq: number;
  // 사용자SEQ(n)...
  userSeqs: number[];
}

export interface ExitForcingResponse extends ProtocolResponse {
  // 대화방SEQ(s)
  roomSeq: string;
  // 강퇴요청타입(s)
  type: RoomExitType;
  // sender사용자SEQ(n)
  senderSeq: number;
  // 사용자SEQ(n)...
  userSeqs: number[];
}

export interface ExitForcingNotification extends ProtocolNotification {
  // 대화방SEQ(s)
  roomSeq: string;
  // 강퇴요청타입(s)
  type: RoomExitType;
  // sender사용자SEQ(n)
  senderSeq: number;
  // 사용자SEQ(n)...
  userSeqs: number[];
}

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

  bodyList.push({ type: PacketBodyValue.String, value: req.roomSeq });
  bodyList.push({ type: PacketBodyValue.String, value: req.type });
  bodyList.push({ type: PacketBodyValue.Integer, value: req.senderSeq });
  req.userSeqs.forEach(userSeq => {
    bodyList.push({ type: PacketBodyValue.Integer, value: userSeq });
  });
  return bodyList;
};

export const decodeExitForcing: ProtocolDecoder<ExitForcingResponse> = (
  message: ProtocolMessage
) => {
  let userSeqs: number[] = [];
  if (message.bodyList.length > 3) {
    userSeqs = message.bodyList.slice(3);
  }
  return decodeProtocolMessage(message, {
    roomSeq: message.bodyList[0],
    type: message.bodyList[1] as RoomExitType,
    senderSeq: message.bodyList[2],
    userSeqs
  } as ExitForcingResponse);
};
export const decodeExitForcingNotification: ProtocolDecoder<ExitForcingNotification> = (
  message: ProtocolMessage
) => {
  let userSeqs: number[] = [];
  if (message.bodyList.length > 3) {
    userSeqs = message.bodyList.slice(3);
  }
  return decodeProtocolMessage(message, {
    roomSeq: message.bodyList[0],
    type: message.bodyList[1] as RoomExitType,
    senderSeq: message.bodyList[2],
    userSeqs
  } as ExitForcingNotification);
};
