import {
  ProtocolRequest,
  ProtocolResponse,
  ProtocolEncoder,
  PacketBody,
  PacketBodyValue,
  ProtocolDecoder,
  ProtocolMessage,
  decodeProtocolMessage
} from '@ucap-webmessenger/protocol';

export interface OpenRequest extends ProtocolRequest {
  // 0. 구분자
  divCd: string;
  // 1n. 초대자 userSeq(n)...
  userSeqs: number[];
}

export interface OpenResponse extends ProtocolResponse {
  // 0. 구분자
  divCd: string;
  // 1. 대화방SEQ(s)
  roomSeq: string;
  // 2.	신규여부(y)
  newRoom: boolean;
}

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

  bodyList.push({ type: PacketBodyValue.String, value: req.divCd });
  for (const userSeq of req.userSeqs) {
    bodyList.push({ type: PacketBodyValue.Integer, value: userSeq });
  }

  return bodyList;
};

export const decodeOpen: ProtocolDecoder<OpenResponse> = (
  message: ProtocolMessage
) => {
  return decodeProtocolMessage(message, {
    divCd: message.bodyList[0],
    roomSeq: message.bodyList[1],
    newRoom: message.bodyList[2] === 'Y' ? true : false
  } as OpenResponse);
};

export interface Open2Request extends ProtocolRequest {
  // 0. 구분자
  divCd: string;
  // 1. 대화방제목(s)
  roomName: string;
  // 2n. 초대자 userSeq(n)...
  userSeqs: number[];
}

export interface Open2Response extends ProtocolResponse {
  // 0. 구분자
  divCd: string;
  // 1. 대화방제목(s)
  roomName: string;
  // 2. 대화방SEQ(s)
  roomSeq: string;
  // 3.	신규여부(y)
  newRoom: boolean;
}

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

  bodyList.push({ type: PacketBodyValue.String, value: req.divCd });
  bodyList.push({ type: PacketBodyValue.String, value: req.roomName.trim() });
  for (const userSeq of req.userSeqs) {
    bodyList.push({ type: PacketBodyValue.Integer, value: userSeq });
  }

  return bodyList;
};

export const decodeOpen2: ProtocolDecoder<Open2Response> = (
  message: ProtocolMessage
) => {
  return decodeProtocolMessage(message, {
    divCd: message.bodyList[0],
    roomName: message.bodyList[1],
    roomSeq: message.bodyList[2],
    newRoom: message.bodyList[3] === 'Y' ? true : false
  } as Open2Response);
};

export interface Open3Request extends ProtocolRequest {
  // 0. 구분자
  divCd: string;
  // 1. 대화방제목(s)
  roomName: string;
  // 2. 타이머대화방여부YN(s)
  isTimerRoom: boolean;
  // 3. 타이머시간(n)
  timerRoomInterval: number;
  // 4n. 초대자 userSeq(n)...
  userSeqs: number[];
}

export interface Open3Response extends ProtocolResponse {
  // 0. 구분자
  divCd: string;
  // 1. 대화방제목(s)
  roomName: string;
  // 2. 대화방SEQ(s)
  roomSeq: string;
  // 3.	신규여부(y)
  newRoom: boolean;
  // 4. 타이머대화방여부YN(s)
  isTimerRoom: boolean;
  // 5. 타이머시간(n)
  timerRoomInterval: number;
}

export const encodeOpen3: ProtocolEncoder<Open3Request> = (
  req: Open3Request
) => {
  const bodyList: PacketBody[] = [];
  let roomName: string = req.roomName.trim();
  if (roomName.length === 0) {
    roomName = ' ';
  }

  bodyList.push(
    { type: PacketBodyValue.String, value: req.divCd },
    { type: PacketBodyValue.String, value: roomName },
    {
      type: PacketBodyValue.String,
      value: req.isTimerRoom === true ? 'Y' : 'N'
    },
    {
      type: PacketBodyValue.Integer,
      value: req.isTimerRoom !== true ? 0 : req.timerRoomInterval
    }
  );
  for (const userSeq of req.userSeqs) {
    bodyList.push({ type: PacketBodyValue.Integer, value: userSeq });
  }

  return bodyList;
};

export const decodeOpen3: ProtocolDecoder<Open3Response> = (
  message: ProtocolMessage
) => {
  return decodeProtocolMessage(message, {
    divCd: message.bodyList[0],
    roomName: message.bodyList[1],
    roomSeq: message.bodyList[2],
    newRoom: message.bodyList[3] === 'Y' ? true : false,
    isTimerRoom: message.bodyList[4] === 'Y' ? true : false,
    timerRoomInterval: message.bodyList[5] || 0
  } as Open3Response);
};

export interface Open4Request extends ProtocolRequest {
  // 0. 구분자
  divCd: string;
  // 1. 대화방제목(s)
  roomName: string;
  // 2. 타이머대화방여부YN(s)
  isTimerRoom: boolean;
  // 3. 타이머시간(n)
  timerRoomInterval: number;
  // 4n. 초대자 userSeq(n)...
  userSeqs: number[];
}

export interface Open4Response extends ProtocolResponse {
  // 0. 구분자
  divCd: string;
  // 1. 대화방제목(s)
  roomName: string;
  // 2. 대화방SEQ(s)
  roomSeq: string;
  // 3.	신규여부(y)
  newRoom: boolean;
  // 4. 타이머대화방여부YN(s)
  isTimerRoom: boolean;
  // 5. 타이머시간(n)
  timerRoomInterval: number;
}

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

  bodyList.push({ type: PacketBodyValue.String, value: req.divCd });
  bodyList.push({ type: PacketBodyValue.String, value: req.roomName.trim() });
  bodyList.push({
    type: PacketBodyValue.String,
    value: req.isTimerRoom === true ? 'Y' : 'N'
  });
  bodyList.push({
    type: PacketBodyValue.Integer,
    value: req.isTimerRoom !== true ? 0 : req.timerRoomInterval
  });
  for (const userSeq of req.userSeqs) {
    bodyList.push({ type: PacketBodyValue.Integer, value: userSeq });
  }

  return bodyList;
};

export const decodeOpen4: ProtocolDecoder<Open4Response> = (
  message: ProtocolMessage
) => {
  return decodeProtocolMessage(message, {
    divCd: message.bodyList[0],
    roomName: message.bodyList[1],
    roomSeq: message.bodyList[2],
    newRoom: message.bodyList[3] === 'Y' ? true : false,
    isTimerRoom: message.bodyList[4] === 'Y' ? true : false,
    timerRoomInterval:
      message.bodyList[4] !== 'Y' ? 0 : message.bodyList[5] || 0
  } as Open4Response);
};
