import * as plugins from './letterxpress.plugins.js';

export interface ILetterXpressConstructorOptions {
  username: string;
  apiKey: string;
}

export class LetterXpressAccount {
  // STATIC
  public static async createAndStart(optionsArg: ConstructorParameters<typeof LetterXpressAccount>[0]) {
    const letterXpressInstance = new LetterXpressAccount(optionsArg);
    await letterXpressInstance.start();
    return letterXpressInstance;
  }

  // INSTANCE
  public baseApiUrl = 'https://api.letterxpress.de/v2';
  public options: ILetterXpressConstructorOptions;
  public deesDocumentInstance: plugins.deesDocument.PdfService;

  public letterSentObservable = new plugins.smartrx.rxjs.Subject<plugins.tsclass.business.ILetter>();

  constructor(optionsArg: ILetterXpressConstructorOptions) {
    const done = plugins.smartpromise.defer();
    this.options = optionsArg;
  }

  public async start() {
    this.deesDocumentInstance = await plugins.deesDocument.PdfService.createAndStart({});
  }

  /**
   * sends a letter
   * @param letterArg
   */
  public async sendLetter(letterArg: plugins.tsclass.business.ILetter) {
    const pdfToSend = await this.deesDocumentInstance.createPdfFromLetterObject({letterData: letterArg, documentSettings: {}});
    const response = await this.request('/printjobs', 'POST', {
      letter: {
        base64_file: plugins.smartbuffer.uInt8ArrayToBase64(pdfToSend.buffer),
        base64_file_checksum: await plugins.smarthash.md5FromString(
          plugins.smartbuffer.uInt8ArrayToBase64(pdfToSend.buffer)
        ),
        specification: {
          color: '4',
          mode: 'simplex',
          shipping: letterArg.to.address.country === 'Germany' ? 'national' : 'international',
        },
      },
    });
    letterArg.objectActions.push({
      name: 'letterxpress-sent',
      message: 'requested letterxpress to send the letter',
      privateMessage: null,
      data: response.body.data.id,
      timestamp: Date.now(),
      userId: null
    })
    return letterArg;
  }

  public async cancelLetter(letterArg: plugins.tsclass.business.ILetter) {
    const processingId = letterArg.objectActions.reduce<string>((previousVal, currentVal) => {
      if (currentVal.name === 'letterxpress-sent') {
        return currentVal.data
      } else {
        return previousVal;
      }
    }, null);
    return await this.cancelLetterByProcessingId(processingId);
  }

  public async cancelLetterByProcessingId(processingId: string) {
    const response = await this.request(`/printjobs/${processingId}`, 'DELETE', {});
    return response;
  }

  /**
   * fires the request
   */
  private async request(routeArg: string, methodArg: 'GET' | 'POST' | 'DELETE', payload: any) {
    const requestUrl = `${this.baseApiUrl}${routeArg}`;
    console.log(requestUrl);
    const requestData = {
      auth: {
        mode: "live",
        username: this.options.username,
        apikey: this.options.apiKey,
      },
      ...payload,
    };
    // console.log(methodArg);
    // console.log(requestData);
    const response = await plugins.smartrequest.request(requestUrl, {
      method: methodArg,
      headers: {
        'Content-Type': 'application/json',
      },
      requestBody: JSON.stringify(requestData),
      keepAlive: false,
    });
    console.log(response.body);
    return response;
  }

  public async stop() {
    await this.deesDocumentInstance.stop();
  }
}