import { BadGatewayException, HttpException, Injectable } from '@nestjs/common';
import { HttpService as AxiosService } from '@nestjs/axios';
import { lastValueFrom } from 'rxjs';
import { LoggerService } from 'src/common/logger/logger.service';
import { error_message } from 'src/common/error_message';
import * as moment from 'moment-timezone';
import _ from 'lodash';
const short = require('short-uuid');

@Injectable()
export class HttpService {
    constructor(
      private http: AxiosService,
      private loggerService: LoggerService
    ) {}

    async sendRequest(method = "get", url, headers = {}, data = {}, showError = true) {
        let response;
        const session = short.generate(), start = moment();
        this.loggerService.requestOut({
            method,
            url,
            headers,
            data
        }, session)
        try {
            switch (method) {
                case "get":
                    response = await this.get(url, headers);
                    this.loggerService.responseIn('success', response, session, moment().diff(start, 'millisecond'))
                    return response
                    break;
    
                case "post":
                    response = await this.post(url, headers, data);
                    this.loggerService.responseIn('success', response, session, moment().diff(start, 'millisecond'))
                    return response
                    break;
    
                case "put":
                    response = await this.put(url, headers, data);
                    this.loggerService.responseIn('success', response, session, moment().diff(start, 'millisecond'))
                    return response
                    break;
    
                case "patch":
                    response = await this.patch(url, headers, data);
                    this.loggerService.responseIn('success', response, session, moment().diff(start, 'millisecond'))
                    return response
                    break;
    
                case "delete":
                    response = await this.delete(url, headers);
                    this.loggerService.responseIn('success', response, session, moment().diff(start, 'millisecond'))
                    return response
                    break;
            } 
        } catch (error) {
            if (error?.response?.data) {
                this.loggerService.responseIn('error', error.response.data, session, moment().diff(start, 'millisecond'))
                if (showError) {
                    throw new BadGatewayException(error.response.data);
                } else {
                    return false
                }
            } else {
                this.loggerService.responseIn('error', error, session, moment().diff(start, 'millisecond'))
                if (showError) {
                    throw new BadGatewayException(error_message.connection_refused);
                } else {
                    return false
                }
            }
        }
    }

    private async get(url, headers) {
        const request = await this.http.get(url, headers);
        return await (await lastValueFrom(request)).data;
    }

    private async post(url, headers, payload) {
        const request = await this.http.post(url, payload, headers);
        return await (await lastValueFrom(request)).data;
    }

    private async put(url, headers, payload) {
        const request = await this.http.put(url, payload, headers);
        return await (await lastValueFrom(request)).data;
    }

    private async patch(url, headers, payload) {
        const request = await this.http.patch(url, payload, headers);
        return await (await lastValueFrom(request)).data;
    }

    private async delete(url, headers) {
        const request = await this.http.delete(url, headers);
        return await (await lastValueFrom(request)).data;
    }
}
