import { Injectable, Logger, HttpException, HttpStatus } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { ConfigService } from '@nestjs/config';
import { firstValueFrom, catchError } from 'rxjs';
import { AxiosError } from 'axios';

@Injectable()
export class CloudflareService {
    private readonly logger = new Logger(CloudflareService.name);
    private readonly apiToken: string;
    private readonly zoneId: string;
    private readonly baseUrl = 'https://api.cloudflare.com/client/v4';

    constructor(
        private readonly httpService: HttpService,
        private readonly configService: ConfigService,
    ) {
        this.apiToken =
            this.configService.get<string>('CLOUDFLARE_API_TOKEN') || '';
        this.zoneId = this.configService.get<string>('CLOUDFLARE_ZONE_ID') || '';

        if (!this.apiToken) {
            this.logger.warn('CLOUDFLARE_API_TOKEN is not set');
        }
    }

    private getHeaders() {
        return {
            Authorization: `Bearer ${this.apiToken}`,
            'Content-Type': 'application/json',
        };
    }

    async listZones(): Promise<any> {
        const url = `${this.baseUrl}/zones`;
        const response = await firstValueFrom(
            this.httpService.get(url, { headers: this.getHeaders() }).pipe(
                catchError((error: AxiosError) => {
                    this.logger.error(error.response?.data || error.message);
                    throw new HttpException(
                        'Failed to fetch Cloudflare zones',
                        HttpStatus.BAD_GATEWAY,
                    );
                }),
            ),
        );
        return response.data;
    }

    async purgeCache(params: {
        purge_everything?: boolean;
        files?: string[];
        tags?: string[];
        hosts?: string[];
    }): Promise<any> {
        if (!this.zoneId) {
            throw new HttpException(
                'CLOUDFLARE_ZONE_ID is not configured',
                HttpStatus.BAD_REQUEST,
            );
        }

        const url = `${this.baseUrl}/zones/${this.zoneId}/purge_cache`;

        const response = await firstValueFrom(
            this.httpService.post(url, params, { headers: this.getHeaders() }).pipe(
                catchError((error: AxiosError) => {
                    this.logger.error(error.response?.data || error.message);
                    throw new HttpException(
                        'Failed to purge Cloudflare cache',
                        HttpStatus.BAD_GATEWAY,
                    );
                }),
            ),
        );

        return response.data;
    }
}
