import { Injectable } from "@angular/core";
import { ServerRestApiService } from "../services/server-rest-api.service";
import {
  deletePaymentBillingQuery,
  editBuyCodeQuery,
  getBuyCodeQuery,
  getPaymentBillingsQuery,
  getPaymentShopDataQuery,
  paymentOrderQuery,
  paymentParseBackQuery,
  preparePaymentOrderQuery,
  savePaymentBillingQuery,
} from "./querys";
import {
  BackDataRecord,
  PaymentBillings,
  PaymentBillingsData,
  PaymentBuyCodeRecord,
  PaymentPreapreResult,
  PaymentPrepareData,
  PaymentPrepareResultRecord,
  PaymentRecordOrder,
  PaymentShopData,
} from "./query-records/payment-records";

export class PaymentServerError extends Error {
  public error;
  constructor(message) {
    super(JSON.stringify(message.error));

    this.error = message;
    this.name = "PaymentServerError";
  }
}

export class PaymentValidationError extends Error {
  public error;
  constructor(message) {
    super(JSON.stringify(message.error));

    this.error = message;
    this.name = "PaymentValidationError";
  }
}

@Injectable({
  providedIn: "root",
})
export class PaymentService {
  constructor(private serverRestApiService: ServerRestApiService) {
  }

  private restHandle(p: Promise<any>): Promise<any> {
    return p
      .catch((err) => {
        throw new PaymentServerError(err);
      })
      .then((res) => {
        if (res.response.error !== undefined) {
          throw new PaymentValidationError(res.response);
        } else {
          return res;
        }
      });
  }

  public getPaymentShopData(): Promise<PaymentShopData> {
    return this.restHandle(
      this.serverRestApiService.query({
        query: getPaymentShopDataQuery,
      })
    );
  }

  public getPaymentBillings(): Promise<PaymentBillings> {
    return this.restHandle(
      this.serverRestApiService.query({
        query: getPaymentBillingsQuery,
      })
    );
  }

  /**
   *
   * @param {PaymentBillingsData} data
   * @returns billing_id
   */
  public savePaymentBilling(data: PaymentBillingsData): Promise<number> {
    return this.restHandle(
      this.serverRestApiService.mutate({
        query: savePaymentBillingQuery,
        variables: { billing: data },
      })
    ).then((res) => {
      return res.billing_id;
    });
  }

  /**
   *
   * @param billingId
   * @param data
   * @returns billing_id
   */
  public editPaymentBilling(
    billingId,
    data: PaymentBillingsData
  ): Promise<number> {
    return this.restHandle(
      this.serverRestApiService.mutate({
        query: savePaymentBillingQuery,
        variables: { billing: Object.assign(data, { billing_id: billingId }) },
      })
    ).then((res) => {
      return res.billing_id;
    });
  }

  /**
   *
   * @param billingId
   * @returns billing_id
   */
  public deletePaymentBilling(billingId): Promise<number> {
    return this.restHandle(
      this.serverRestApiService.mutate({
        query: deletePaymentBillingQuery,
        variables: { billing_id: billingId },
      })
    ).then((res) => {
      return res.billing_id;
    });
  }

  public preparePaymentOrder(
    data: PaymentPrepareData
  ): Promise<PaymentPreapreResult> {
    return this.restHandle(
      this.serverRestApiService.mutate({
        query: preparePaymentOrderQuery,
        variables: { order: data },
      })
    );
  }

  public getBuyCode(): Promise<PaymentBuyCodeRecord> {
    return this.serverRestApiService.query({
      query: getBuyCodeQuery,
    });
  }

  public editBuyCode(buyCode: string): Promise<boolean> {
    return this.serverRestApiService.mutate({
      query: editBuyCodeQuery,
      variables: {
        buyCode,
      },
    });
  }

  public startPaymentOrder(paymentOrder: PaymentRecordOrder): Promise<string>{
    return this.serverRestApiService.mutate({
      query: paymentOrderQuery,
      variables:{
        order: paymentOrder.order,
        orderHash: paymentOrder.orderHash,
        language: paymentOrder.language
      }
    });
  }

  public paymentParseBack(result: string, signature: string): Promise<BackDataRecord>{
    return this.serverRestApiService.query({
      query: paymentParseBackQuery,
      variables:{
        result: result,
        signature: signature
      }
    });
  }
}
