"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BearerTokenService = void 0;
const common_1 = require("@nestjs/common");
const axios_1 = require("@nestjs/axios");
const rxjs_1 = require("rxjs");
const cloud_provider_enum_1 = require("../../providers/enums/cloud-provider.enum");
let BearerTokenService = class BearerTokenService {
    constructor(httpService) {
        this.httpService = httpService;
    }
    async generateToken(provider, dto) {
        try {
            switch (provider) {
                case cloud_provider_enum_1.CloudProvider.CONTABO:
                    return this.generateContaboToken(dto);
                case cloud_provider_enum_1.CloudProvider.HETZNER:
                    return this.generateHetznerToken(dto);
                default:
                    throw new common_1.HttpException(`Provider ${provider} not supported`, common_1.HttpStatus.BAD_REQUEST);
            }
        }
        catch (error) {
            throw new common_1.HttpException(error.response?.data?.error || 'Authentication failed', error.response?.status || common_1.HttpStatus.UNAUTHORIZED);
        }
    }
    async generateContaboToken(dto) {
        const response = await (0, rxjs_1.lastValueFrom)(this.httpService.post('https://auth.contabo.com/auth/realms/contabo/protocol/openid-connect/token', new URLSearchParams({
            grant_type: 'password',
            client_id: dto.client_id,
            username: dto.username,
            password: dto.password,
            client_secret: dto.client_secret,
        }), {
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
        }));
        return {
            access_token: response.data.access_token,
            token_type: 'Bearer',
            expires_in: response.data.expires_in,
            refresh_token: response.data.refresh_token,
        };
    }
    async generateHetznerToken(dto) {
        throw new common_1.NotImplementedException('Hetzner uses API keys and does not support OAuth token generation');
    }
    async refreshToken(provider, dto) {
        try {
            switch (provider) {
                case cloud_provider_enum_1.CloudProvider.CONTABO:
                    return this.refreshContaboToken(dto);
                case cloud_provider_enum_1.CloudProvider.HETZNER:
                    return this.refreshHetznerToken(dto);
                default:
                    throw new common_1.HttpException(`Provider ${provider} not supported`, common_1.HttpStatus.BAD_REQUEST);
            }
        }
        catch (error) {
            if (error.response?.status === 400 &&
                (error.response?.data?.error === 'invalid_grant' ||
                    error.response?.data?.error_description?.includes('expired'))) {
                throw new common_1.HttpException('Refresh token has expired. Please log in again.', common_1.HttpStatus.UNAUTHORIZED);
            }
            throw new common_1.HttpException(error.response?.data?.error_description ||
                error.response?.data?.error ||
                'Token refresh failed', error.response?.status || common_1.HttpStatus.UNAUTHORIZED);
        }
    }
    async refreshContaboToken(dto) {
        const response = await (0, rxjs_1.lastValueFrom)(this.httpService.post('https://auth.contabo.com/auth/realms/contabo/protocol/openid-connect/token', new URLSearchParams({
            grant_type: 'refresh_token',
            client_id: dto.client_id,
            client_secret: dto.client_secret,
            refresh_token: dto.refresh_token,
        }), {
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
        }));
        return {
            access_token: response.data.access_token,
            token_type: 'Bearer',
            expires_in: response.data.expires_in,
            refresh_token: response.data.refresh_token,
            scope: response.data.scope,
        };
    }
    async refreshHetznerToken(dto) {
        throw new common_1.NotImplementedException('Hetzner uses API keys and does not support OAuth token refresh');
    }
};
exports.BearerTokenService = BearerTokenService;
exports.BearerTokenService = BearerTokenService = __decorate([
    (0, common_1.Injectable)(),
    __metadata("design:paramtypes", [axios_1.HttpService])
], BearerTokenService);
