import crypto from 'crypto';
export class LeadService {
    db;
    constructor(db) {
        this.db = db;
    }
    createLead(data) {
        const id = crypto.randomUUID();
        const meta = data.metadata ? JSON.stringify(data.metadata) : null;
        const now = new Date().toISOString();
        this.db.prepare(`
      INSERT INTO leads (id, email, name, company, metadata, source, source_detail, created_at, updated_at)
      VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
      ON CONFLICT(email) DO UPDATE SET
        name = COALESCE(excluded.name, leads.name),
        company = COALESCE(excluded.company, leads.company),
        metadata = COALESCE(excluded.metadata, leads.metadata),
        source = COALESCE(excluded.source, leads.source),
        source_detail = COALESCE(excluded.source_detail, leads.source_detail),
        updated_at = excluded.updated_at
    `).run(id, data.email, data.name ?? null, data.company ?? null, meta, data.source ?? null, data.source_detail ?? null, now, now);
        return this.db.prepare('SELECT * FROM leads WHERE email = ?').get(data.email);
    }
    getLead(id) {
        return this.db.prepare('SELECT * FROM leads WHERE id = ?').get(id);
    }
    updateLead(id, data) {
        const fields = [];
        const values = [];
        if (data.name !== undefined) {
            fields.push('name = ?');
            values.push(data.name);
        }
        if (data.company !== undefined) {
            fields.push('company = ?');
            values.push(data.company);
        }
        if (data.metadata !== undefined) {
            fields.push('metadata = ?');
            values.push(JSON.stringify(data.metadata));
        }
        if (fields.length === 0)
            return this.getLead(id);
        fields.push('updated_at = ?');
        values.push(new Date().toISOString());
        values.push(id);
        this.db.prepare(`UPDATE leads SET ${fields.join(', ')} WHERE id = ?`).run(...values);
        return this.getLead(id);
    }
    deleteLead(id) {
        const result = this.db.prepare('DELETE FROM leads WHERE id = ?').run(id);
        return result.changes > 0;
    }
    addTags(leadId, tags) {
        const stmt = this.db.prepare('INSERT OR IGNORE INTO lead_tags (lead_id, tag) VALUES (?, ?)');
        const tx = this.db.transaction((items) => {
            for (const tag of items)
                stmt.run(leadId, tag);
        });
        tx(tags);
    }
    removeTags(leadId, tags) {
        const stmt = this.db.prepare('DELETE FROM lead_tags WHERE lead_id = ? AND tag = ?');
        const tx = this.db.transaction((items) => {
            for (const tag of items)
                stmt.run(leadId, tag);
        });
        tx(tags);
    }
    getTagsForLead(leadId) {
        return this.db.prepare('SELECT tag FROM lead_tags WHERE lead_id = ? ORDER BY tag').all(leadId).map(r => r.tag);
    }
    addToList(leadId, listName) {
        this.db.prepare('INSERT OR IGNORE INTO lead_lists (lead_id, list_name) VALUES (?, ?)').run(leadId, listName);
    }
    removeFromList(leadId, listName) {
        this.db.prepare('DELETE FROM lead_lists WHERE lead_id = ? AND list_name = ?').run(leadId, listName);
    }
    getListsForLead(leadId) {
        return this.db.prepare('SELECT list_name FROM lead_lists WHERE lead_id = ? ORDER BY list_name').all(leadId).map(r => r.list_name);
    }
    queryLeads(filters) {
        const page = filters.page ?? 1;
        const limit = filters.limit ?? 50;
        const offset = (page - 1) * limit;
        const conditions = [];
        const params = [];
        if (filters.status) {
            conditions.push('l.status = ?');
            params.push(filters.status);
        }
        if (filters.source) {
            conditions.push('l.source = ?');
            params.push(filters.source);
        }
        if (filters.search) {
            conditions.push('(l.email LIKE ? OR l.name LIKE ?)');
            params.push(`%${filters.search}%`, `%${filters.search}%`);
        }
        if (filters.tag) {
            conditions.push('EXISTS (SELECT 1 FROM lead_tags lt WHERE lt.lead_id = l.id AND lt.tag = ?)');
            params.push(filters.tag);
        }
        if (filters.list) {
            conditions.push('EXISTS (SELECT 1 FROM lead_lists ll WHERE ll.lead_id = l.id AND ll.list_name = ?)');
            params.push(filters.list);
        }
        const where = conditions.length ? `WHERE ${conditions.join(' AND ')}` : '';
        const total = this.db.prepare(`SELECT COUNT(*) as count FROM leads l ${where}`).get(...params).count;
        const data = this.db.prepare(`SELECT l.* FROM leads l ${where} ORDER BY l.created_at DESC LIMIT ? OFFSET ?`).all(...params, limit, offset);
        return { data, total };
    }
    unsubscribe(email) {
        const result = this.db.prepare("UPDATE leads SET status = 'unsubscribed', updated_at = ? WHERE email = ?").run(new Date().toISOString(), email);
        if (result.changes > 0) {
            this.db.prepare("DELETE FROM email_queue WHERE lead_id = (SELECT id FROM leads WHERE email = ?) AND status = 'pending'").run(email);
        }
        return result.changes > 0;
    }
    getListsWithCounts() {
        return this.db.prepare('SELECT list_name, COUNT(*) as count FROM lead_lists GROUP BY list_name ORDER BY list_name').all();
    }
    getTagsWithCounts() {
        return this.db.prepare('SELECT tag, COUNT(*) as count FROM lead_tags GROUP BY tag ORDER BY tag').all();
    }
    importBatch(leads, sourceDetail, source) {
        let imported = 0;
        const tx = this.db.transaction(() => {
            for (const lead of leads) {
                this.createLead({ ...lead, source, source_detail: sourceDetail });
                imported++;
            }
        });
        tx();
        return { imported };
    }
}
//# sourceMappingURL=lead-service.js.map