import { Injectable } from '@angular/core';

import { Observable } from 'rxjs';
import { map, takeWhile, timeout, take } from 'rxjs/operators';

import { ProtocolService } from '@ucap-webmessenger/protocol';

import {
  InfoRequest,
  InfoResponse,
  encodeInfo,
  decodeInfo,
  decodeInfoData,
  InfoData
} from '../models/info';
import {
  SVC_TYPE_EVENT,
  SSVC_TYPE_EVENT_INFO_REQ,
  SSVC_TYPE_EVENT_INFO_RES,
  SSVC_TYPE_EVENT_INFO_DATA,
  SSVC_TYPE_EVENT_SEND_REQ
} from '../types/service';
import {
  EventSendRequest,
  EventSendResponse,
  decodeEventSend,
  encodeEventSend
} from '../models/event-send';

@Injectable({
  providedIn: 'root'
})
export class EventProtocolService {
  constructor(private protocolService: ProtocolService) {}

  public info(req: InfoRequest): Observable<InfoResponse | InfoData> {
    return this.protocolService
      .call(SVC_TYPE_EVENT, SSVC_TYPE_EVENT_INFO_REQ, ...encodeInfo(req))
      .pipe(
        takeWhile(res => SSVC_TYPE_EVENT_INFO_RES !== res.subServiceType, true),
        map(res => {
          if (SSVC_TYPE_EVENT_INFO_DATA === res.subServiceType) {
            return {
              ...decodeInfoData(res),
              Type: SSVC_TYPE_EVENT_INFO_DATA
            };
          }
          return {
            ...decodeInfo(res),
            Type: SSVC_TYPE_EVENT_INFO_RES
          };
        })
      );
  }

  public eventSend(req: EventSendRequest): Observable<EventSendResponse> {
    return this.protocolService
      .call(SVC_TYPE_EVENT, SSVC_TYPE_EVENT_SEND_REQ, ...encodeEventSend(req))
      .pipe(
        take(1),
        map(res => {
          return decodeEventSend(res);
        })
      );
  }
}
