import { Injectable } from '@angular/core';
import { NatsService } from 'app/core/nats/services/nats.service';
import * as nats from 'nats.ws';

import { Error } from 'app/modules/proto/protobuf/rpc_pb';

import {
  GetMemberByUsernameRequest,
  GetMemberByUsernameResponse,
  GetMemberRequest,
  GetMemberResponse,
  UpdateMemberRequest,
  UpdateMemberResponse,
  CreateMemberResponse,
  CreateMemberRequest,
  UpdateMemberForPasswordResponse,
  UpdateMemberForPasswordRequest,
} from 'app/modules/proto/c2se/member_pb';
import {
  SUBJECT_GET_MEMBER,
  SUBJECT_GET_MEMBER_BY_USERNAME,
  SUBJECT_UPDATE_MEMBER,
  SUBJECT_CREATE_MEMBER,
  SUBJECT_UPDATE_MEMBER_FOR_PASSWORD,
} from 'app/modules/proto/c2se/frontend/member_pb';
import { Pagination } from 'app/modules/proto/protobuf/pagination_pb';

@Injectable({
  providedIn: 'root',
})
export class MemberService {
  /**
   * Constructor
   */
  constructor(private __natsService: NatsService) {}

  // -----------------------------------------------------------------------------------------------------
  // @ Accessors
  // -----------------------------------------------------------------------------------------------------

  // -----------------------------------------------------------------------------------------------------
  // @ Public methods
  // -----------------------------------------------------------------------------------------------------

  getMember(id: string): Promise<GetMemberResponse.Result> {
    return new Promise<GetMemberResponse.Result>((resolve, reject) => {
      let req = new GetMemberRequest();
      req.setId(id);

      this.__natsService
        .request<GetMemberResponse.Result>(
          SUBJECT_GET_MEMBER,
          req.serializeBinary(),
          GetMemberResponse.deserializeBinary
        )
        .then((result) => {
          console.log('success', result, result.getMember());
          resolve(result);
        })
        .catch((e: Error) => {
          console.log('failed', e);
          reject(e);
        });
    });
  }

  getMemberByUsername(
    username: string
  ): Promise<GetMemberByUsernameResponse.Result> {
    return new Promise<GetMemberByUsernameResponse.Result>(
      (resolve, reject) => {
        let req = new GetMemberByUsernameRequest();
        req.setUsername(username);

        this.__natsService
          .request<GetMemberByUsernameResponse.Result>(
            SUBJECT_GET_MEMBER_BY_USERNAME,
            req.serializeBinary(),
            GetMemberByUsernameResponse.deserializeBinary
          )
          .then((result) => {
            resolve(result);
          })
          .catch((e: Error) => {
            console.log('failed', e);
            reject(e);
          });
      }
    );
  }

  updateMember(
    id: string,
    siteId: string,
    memberLevelId: string,
    mobilePhoneNumber: string
  ): Promise<UpdateMemberResponse.Result> {
    return new Promise<UpdateMemberResponse.Result>((resolve, reject) => {
      let req = new UpdateMemberRequest();
      req.setId(id);

      if (!!siteId) {
        req.setSiteId(siteId);
      }
      if (!!memberLevelId) {
        req.setMemberLevelId(memberLevelId);
      }
      if (!!mobilePhoneNumber) {
        req.setMobilePhoneNumber(mobilePhoneNumber);
      }

      this.__natsService
        .request<UpdateMemberResponse.Result>(
          SUBJECT_UPDATE_MEMBER,
          req.serializeBinary(),
          UpdateMemberResponse.deserializeBinary
        )
        .then((result) => {
          console.log('updateMember Result: ', result);
          resolve(result);
        })
        .catch((e: Error) => {
          console.log('failed', e);
          reject(e);
        });
    });
  }

  updateMemberForPassword(
    id: string,
    password: string
  ): Promise<UpdateMemberForPasswordResponse.Result> {
    return new Promise<UpdateMemberForPasswordResponse.Result>(
      (resolve, reject) => {
        let req = new UpdateMemberForPasswordRequest();
        req.setId(id);
        req.setPassword(password);

        this.__natsService
          .request<UpdateMemberResponse.Result>(
            SUBJECT_UPDATE_MEMBER_FOR_PASSWORD,
            req.serializeBinary(),
            UpdateMemberResponse.deserializeBinary
          )
          .then((result) => {
            console.log('updateMemberForPassword Result: ', result);
            resolve(result);
          })
          .catch((e: Error) => {
            console.log('failed', e);
            reject(e);
          });
      }
    );
  }

  // siteId: 8429a7ab-b9de-400b-a209-28ff46e22bec
  // classId: 4b014ef5-3bab-4413-aaf9-b0040a70ec77
  // levelId: c56231ac-2120-4a81-a30a-5d41fafb6c57

  createMember(req: CreateMemberRequest): Promise<CreateMemberResponse.Result> {
    return new Promise<CreateMemberResponse.Result>((resolve, reject) => {
      this.__natsService
        .request<CreateMemberResponse.Result>(
          SUBJECT_CREATE_MEMBER,
          req.serializeBinary(),
          CreateMemberResponse.deserializeBinary
        )
        .then((result) => {
          console.log('createMember Result: ', result);
          resolve(result);
        })
        .catch((e: Error) => {
          console.log('failed', e);
          reject(e);
        });
    });
  }
}
