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/protobuf/protobuf/rpc/error_pb';

import {
  ListMembersRequest,
  ListMembersResponse,
  GetMemberByUsernameRequest,
  GetMemberByUsernameResponse,
  GetMemberRequest,
  GetMemberResponse,
  SUBJECT_LIST_MEMBERS,
  SUBJECT_GET_MEMBER,
  SUBJECT_GET_MEMBER_BY_USERNAME,
  UpdateMemberRequest,
  UpdateMemberResponse,
  SUBJECT_UPDATE_MEMBER,
} from 'app/modules/protobuf/c2se/backend/member_pb';
import { Pagination } from 'app/modules/protobuf/protobuf/pagination/pagination_pb';

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

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

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

  listMembers(req?: ListMembersRequest): Promise<ListMembersResponse.Result> {
    return new Promise<ListMembersResponse.Result>((resolve, reject) => {
      if (!req) {
        req = new ListMembersRequest();
      }

      if (!req.hasPagination()) {
        let paging = new Pagination();
        paging.setPageSize(10);
        paging.setPage(0);

        req.setPagination(paging);
      }

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

  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(): Promise<GetMemberByUsernameResponse.Result> {
    return new Promise<GetMemberByUsernameResponse.Result>(
      (resolve, reject) => {
        let req = new GetMemberByUsernameRequest();

        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,
    password: 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 (!!password) {
        req.setPassword(password);
      }
      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);
        });
    });
  }

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

  // createMember(
  //   siteId: string = '8429a7ab-b9de-400b-a209-28ff46e22bec',
  //   memberLevelId: string = 'c56231ac-2120-4a81-a30a-5d41fafb6c57',
  //   classId: string = '4b014ef5-3bab-4413-aaf9-b0040a70ec77',
  //   signinId: string,
  //   nickname: string,
  //   password: string,
  //   mobilePhoneNumber: string
  // ): Promise<MemberRequ.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 (!!password) {
  //       req.setPassword(password);
  //     }
  //     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);
  //       });
  //   });
  // }
}
