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 {
  ListBanksRequest,
  ListBanksResponse,
  CreateBankRequest,
  CreateBankResponse,
  UpdateBankRequest,
  UpdateBankResponse,
  DeleteBankRequest,
  DeleteBankResponse,
  GetBankResponse,
  GetBankRequest,
} from 'app/modules/proto/c2se/bank_pb';
import {
  SUBJECT_LIST_BANKS,
  SUBJECT_CREATE_BANK,
  SUBJECT_UPDATE_BANK,
  SUBJECT_DELETE_BANK,
  SUBJECT_GET_BANK,
} from 'app/modules/proto/c2se/backend/bank_pb';

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

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

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

  createBank(): Promise<CreateBankResponse.Result> {
    return new Promise<CreateBankResponse.Result>((resolve, reject) => {
      let req = new CreateBankRequest();

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

  listBanks(): Promise<ListBanksResponse.Result> {
    return new Promise<ListBanksResponse.Result>((resolve, reject) => {
      let req = new ListBanksRequest();

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

  getBank(): Promise<GetBankResponse.Result> {
    return new Promise<GetBankResponse.Result>((resolve, reject) => {
      let req = new GetBankRequest();

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

  updateBank(): Promise<UpdateBankResponse.Result> {
    return new Promise<UpdateBankResponse.Result>((resolve, reject) => {
      let req = new UpdateBankRequest();

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

  deleteBank(): Promise<DeleteBankResponse.Result> {
    return new Promise<DeleteBankResponse.Result>((resolve, reject) => {
      let req = new DeleteBankRequest();

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