import { Injectable } from '@severo-tech/injection-decorator';
import { BadGateway } from '@somma/node-errors';
import axios, { isAxiosError } from 'axios';
import {
  IDebitClient,
  IDebitClientFilter,
} from '../../application/contracts';
import { Base01EUSTClient } from './base-01eust-client';
import { RetryMethod } from '../../application/decorators';
import { IPagination } from '../../domain/pagination';
import { Debit } from '../../domain/debit';

@Injectable()
export class Debit01EUSTClient extends Base01EUSTClient implements IDebitClient {
  @RetryMethod({ ms: 500 })
  public async find(filters: IDebitClientFilter, limit = 50, offset = 1): Promise<Debit[]> {
    const url = `${this.baseURL}/v1/debits`;

    const params = {
      ...filters,
      limit,
      offset,
    };

    const headers = {
      Authorization: await this.getToken(),
    };

    this.logger.debug(
      `"Debit01EUSTClient.find" - Sending GET request to url [${url}] with params [${JSON.stringify(params)}]`,
    );

    try {
      const { data: response } = await axios.get<IPagination<Debit[]>>(url, {
        params,
        headers,
      });

      if (response.count > limit * offset) {
        const aggregation = await this.find(filters, limit, offset + 1);
        return [...response.data, ...aggregation];
      }

      return response.data;
    } catch (error) {
      const message = `Cannot get Debit: GET - "${url}" | params: [${JSON.stringify(params)}]`;
      const err = isAxiosError(error) ? error.response?.data : error;
      this.logger.error(message, err);
      throw new BadGateway(message, undefined, err);
    }
  }

  @RetryMethod({ ms: 500 })
  public async create(body: Partial<Debit>): Promise<Debit> {
    const url = `${this.baseURL}/v1/debits`;

    const headers = {
      Authorization: await this.getToken(),
    };

    this.logger.debug(
      `"Debit01EUSTClient.create" - Sending GET request to url [${url}] with body [${JSON.stringify(body)}]`,
    );

    try {
      const { data } = await axios.post<Debit>(url, body, { headers });

      return data;
    } catch (error) {
      const message = `Cannot Create Debit: POST - "${url}" | Body: [${JSON.stringify(body)}]`;
      const err = isAxiosError(error) ? error.response?.data : error;
      this.logger.error(message, err);
      throw new BadGateway(message, undefined, err);
    }
  }
}
