import { Inject } from '@severo-tech/injection-decorator';
import { BadGateway } from '@somma/node-errors';
import axios, { isAxiosError } from 'axios';
import { ILogger } from '../../application/contracts';
import { RetryMethod } from '../../application/decorators';

export abstract class Base01EUSTClient {
  protected readonly baseURL = process.env.API_01EUST_URL;

  private readonly loginBaseURL = process.env.API_01CM_URL;

  private readonly user = process.env.API_01CM_USER;

  private readonly password = process.env.API_01CM_PASSWORD;

  private expiresIn!: Date;

  private token: string = '';

  @Inject('ZenviaLogger')
  protected readonly logger!: ILogger;

  @RetryMethod({ ms: 500 })
  protected async getToken(): Promise<string> {
    const date = new Date();
    if (this.token && date < this.expiresIn) {
      this.logger.debug('"Base01EUSTClient.getToken" - Token is valid (Skipping login)');
      return this.token;
    }

    const url = `${this.loginBaseURL}/sessions`;

    const body = {
      email: this.user,
      password: this.password,
    };

    try {
      this.logger.debug(`"Base01EUSTClient.getToken" - Making request to url [${url}]`);

      const response = await axios.post(url, body);

      this.expiresIn = new Date(date.setMinutes(date.getMinutes() + 5));

      this.token = `Bearer ${response?.data?.token}`;
      return this.token;
    } catch (error) {
      const message = `Cannot Login on 01CM API: POST - "${url}"`;
      const err = isAxiosError(error) ? { causedBy: error.response?.data } : error;
      this.logger.error(message, err);
      throw new BadGateway(message, undefined, err);
    }
  }
}
