const BASE_URL = 'https://api.hosting.ionos.com/dns/v1';
export class IonosDnsAdapter {
    credentials;
    logger;
    constructor(credentials, logger) {
        this.credentials = credentials;
        this.logger = logger;
    }
    async upsertRecord(params) {
        const { domain, type, value, zone: zoneName } = params;
        const headers = this.headers();
        // Find zone
        const spinner = this.logger.step(`Buscando zona DNS "${zoneName}" en IONOS...`);
        const zone = await this.findZone(zoneName, headers);
        spinner.succeed(`Zona encontrada: ${zone.name} (${zone.id})`);
        // Check existing record
        const existing = await this.findExistingRecord(zone.id, domain, type, headers);
        if (existing) {
            this.logger.warn(`El registro DNS ${type} "${domain}" ya existe con valor ${existing.content}`);
            if (existing.content === value) {
                this.logger.success('Valor coincide, no se requieren cambios.');
                return { action: 'unchanged', domain, recordType: type, value };
            }
            // Update existing
            const updateSpinner = this.logger.step('Actualizando registro DNS existente...');
            const response = await fetch(`${BASE_URL}/zones/${zone.id}/records/${existing.id}`, {
                body: JSON.stringify({
                    content: value,
                    disabled: false,
                    prio: 0,
                    ttl: 3600,
                }),
                headers,
                method: 'PUT',
            });
            if (!response.ok) {
                updateSpinner.fail('Error al actualizar registro DNS');
                throw new Error(`IONOS API error: ${response.status} ${await response.text()}`);
            }
            updateSpinner.succeed(`Registro DNS ${type} actualizado: ${domain} → ${value}`);
            return { action: 'updated', domain, recordType: type, value };
        }
        // Create new
        const createSpinner = this.logger.step(`Creando registro DNS ${type}: ${domain} → ${value}...`);
        const response = await fetch(`${BASE_URL}/zones/${zone.id}/records`, {
            body: JSON.stringify([
                {
                    content: value,
                    disabled: false,
                    name: domain,
                    prio: 0,
                    ttl: 3600,
                    type,
                },
            ]),
            headers,
            method: 'POST',
        });
        if (!response.ok) {
            createSpinner.fail('Error al crear registro DNS');
            throw new Error(`IONOS API error: ${response.status} ${await response.text()}`);
        }
        createSpinner.succeed(`Registro DNS ${type} creado: ${domain} → ${value}`);
        return { action: 'created', domain, recordType: type, value };
    }
    async findExistingRecord(zoneId, recordName, recordType, headers) {
        const response = await fetch(`${BASE_URL}/zones/${zoneId}`, { headers });
        if (!response.ok) {
            throw new Error(`IONOS API error: ${response.status} ${response.statusText}`);
        }
        const zone = (await response.json());
        return zone.records?.find((r) => r.name === recordName && r.type === recordType);
    }
    async findZone(zoneName, headers) {
        const response = await fetch(`${BASE_URL}/zones`, { headers });
        if (!response.ok) {
            throw new Error(`IONOS API error: ${response.status} ${response.statusText}`);
        }
        const zones = (await response.json());
        const zone = zones.find((z) => z.name === zoneName);
        if (!zone) {
            throw new Error(`Zone "${zoneName}" not found in IONOS. Available: ${zones.map((z) => z.name).join(', ')}`);
        }
        return zone;
    }
    headers() {
        return {
            'Content-Type': 'application/json',
            'X-API-Key': this.credentials.apiKey,
        };
    }
}
