"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.listmonkClient = void 0;
const env_1 = require("../config/env");
const logger_1 = require("../utils/logger");
// --- Client ---
class ListmonkClient {
    get baseUrl() {
        return env_1.env.LISTMONK_URL;
    }
    get authHeader() {
        return 'Basic ' + Buffer.from(`${env_1.env.LISTMONK_ADMIN_USER}:${env_1.env.LISTMONK_ADMIN_PASSWORD}`).toString('base64');
    }
    get enabled() {
        return env_1.env.LISTMONK_SYNC_ENABLED === 'true';
    }
    assertEnabled() {
        if (!this.enabled) {
            throw new Error('Listmonk sync is disabled. Set LISTMONK_SYNC_ENABLED=true to enable.');
        }
    }
    async request(method, path, body) {
        const url = `${this.baseUrl}${path}`;
        const controller = new AbortController();
        const timeout = setTimeout(() => controller.abort(), 5000);
        try {
            const res = await fetch(url, {
                method,
                headers: {
                    'Authorization': this.authHeader,
                    'Content-Type': 'application/json',
                },
                body: body ? JSON.stringify(body) : undefined,
                signal: controller.signal,
            });
            if (!res.ok) {
                const text = await res.text().catch(() => '');
                throw new Error(`Listmonk API ${method} ${path} returned ${res.status}: ${text}`);
            }
            return await res.json();
        }
        finally {
            clearTimeout(timeout);
        }
    }
    async checkHealth() {
        try {
            const controller = new AbortController();
            const timeout = setTimeout(() => controller.abort(), 5000);
            try {
                const res = await fetch(`${this.baseUrl}/api/health`, {
                    headers: { 'Authorization': this.authHeader },
                    signal: controller.signal,
                });
                return res.ok;
            }
            finally {
                clearTimeout(timeout);
            }
        }
        catch (err) {
            logger_1.logger.warn('Listmonk health check failed:', err instanceof Error ? err.message : err);
            return false;
        }
    }
    async getLists() {
        this.assertEnabled();
        try {
            const res = await this.request('GET', '/api/lists?per_page=all');
            return res.data.results || [];
        }
        catch (err) {
            logger_1.logger.warn('Failed to fetch Listmonk lists:', err instanceof Error ? err.message : err);
            throw err;
        }
    }
    async createList(name, type, tags) {
        this.assertEnabled();
        try {
            const res = await this.request('POST', '/api/lists', {
                name,
                type,
                optin: 'single',
                tags,
            });
            return res.data;
        }
        catch (err) {
            logger_1.logger.warn(`Failed to create Listmonk list "${name}":`, err instanceof Error ? err.message : err);
            throw err;
        }
    }
    async findSubscriberByEmail(email) {
        this.assertEnabled();
        try {
            const safeEmail = email.replace(/'/g, "''");
            const query = encodeURIComponent(`subscribers.email='${safeEmail}'`);
            const res = await this.request('GET', `/api/subscribers?query=${query}&per_page=1`);
            const results = res.data.results;
            return results && results.length > 0 ? results[0] : null;
        }
        catch (err) {
            logger_1.logger.warn(`Failed to find subscriber ${email}:`, err instanceof Error ? err.message : err);
            return null;
        }
    }
    async createSubscriber(email, name, listIds, attribs) {
        this.assertEnabled();
        const res = await this.request('POST', '/api/subscribers', {
            email,
            name,
            status: 'enabled',
            lists: listIds,
            attribs,
        });
        return res.data;
    }
    async updateSubscriber(id, data) {
        this.assertEnabled();
        const res = await this.request('PUT', `/api/subscribers/${id}`, data);
        return res.data;
    }
    async updateList(id, data) {
        this.assertEnabled();
        const res = await this.request('PUT', `/api/lists/${id}`, data);
        return res.data;
    }
    async deleteList(id) {
        this.assertEnabled();
        await this.request('DELETE', `/api/lists/${id}`);
    }
    async removeSubscriberFromLists(subscriberId, listIdsToRemove, currentEmail, currentListIds) {
        this.assertEnabled();
        const filteredIds = currentListIds.filter(id => !listIdsToRemove.includes(id));
        return this.updateSubscriber(subscriberId, {
            email: currentEmail,
            lists: filteredIds,
        });
    }
    /**
     * Get campaigns with stats (for dashboard)
     */
    async getCampaigns() {
        try {
            const res = await this.request('GET', '/api/campaigns?per_page=all&order_by=updated_at&order=desc');
            return (res.data.results || []).map(c => ({
                id: c.id,
                name: c.name,
                status: c.status,
                sent: c.stats?.sent || 0,
                views: c.stats?.views || 0,
                clicks: c.stats?.clicks || 0,
                started_at: c.started_at,
                updated_at: c.updated_at,
            }));
        }
        catch (err) {
            logger_1.logger.warn('Failed to fetch Listmonk campaigns:', err instanceof Error ? err.message : err);
            return [];
        }
    }
    async upsertSubscriber(email, name, listIds, attribs) {
        this.assertEnabled();
        const existing = await this.findSubscriberByEmail(email);
        if (existing) {
            // Merge lists: combine existing + new, deduplicate
            const existingListIds = existing.lists.map(l => l.id);
            const mergedListIds = [...new Set([...existingListIds, ...listIds])];
            // Merge attribs
            const mergedAttribs = { ...existing.attribs, ...attribs };
            return this.updateSubscriber(existing.id, {
                email,
                name: name || existing.name,
                lists: mergedListIds,
                attribs: mergedAttribs,
            });
        }
        return this.createSubscriber(email, name, listIds, attribs);
    }
}
exports.listmonkClient = new ListmonkClient();
//# sourceMappingURL=listmonk.client.js.map