/**
 * src/agent/proactive.ts
 * المحرك الاستباقي — Proactive messaging engine
 * Periodic checks for follow-ups, daily/weekly reports, reminders
 */
import { createChildLogger } from '../utils/logger.js';
import { supabase } from '../utils/supabase.js';
import { generateDailyReport, generateWeeklyReport } from '../analytics/reports.js';
import { generateReport } from '../media/pdf.js';
import { whatsappClient } from '../channels/whatsapp/client.js';
import { getTenantById } from '../tenants/manager.js';
const log = createChildLogger('agent:proactive');
// ─── State ───────────────────────────────────────────────────────────
const activeEngines = new Map();
/** Track last execution times to prevent duplicate runs */
const lastRuns = {};
// ─── Saudi Time Helpers ──────────────────────────────────────────────
function getSaudiTime() {
    return new Date(new Date().toLocaleString('en-US', { timeZone: 'Asia/Riyadh' }));
}
function getSaudiHour() {
    return getSaudiTime().getHours();
}
function getSaudiDay() {
    return getSaudiTime().getDay(); // 0 = Sunday
}
function todayKey() {
    return getSaudiTime().toISOString().slice(0, 10);
}
// ─── Proactive Engine ────────────────────────────────────────────────
/**
 * بدء المحرك الاستباقي لمستأجر — يتحقق دورياً من المهام المطلوبة
 * يعمل كل 15 دقيقة ويتحقق من الوقت لتنفيذ المهام المجدولة
 */
export function startProactiveEngine(tenantId) {
    if (activeEngines.has(tenantId)) {
        log.warn({ tenantId }, 'Proactive engine already running');
        return;
    }
    log.info({ tenantId }, 'Starting proactive engine');
    // Initialize last runs tracking
    if (!lastRuns[tenantId]) {
        lastRuns[tenantId] = {};
    }
    const intervalId = setInterval(() => {
        runProactiveChecks(tenantId).catch(err => {
            log.error({ tenantId, error: err instanceof Error ? err.message : String(err) }, 'Proactive check failed');
        });
    }, 15 * 60 * 1000); // كل 15 دقيقة
    activeEngines.set(tenantId, {
        tenantId,
        intervalId,
        isRunning: true,
    });
    // Run immediately on start
    runProactiveChecks(tenantId).catch(err => {
        log.error({ tenantId, error: err instanceof Error ? err.message : String(err) }, 'Initial proactive check failed');
    });
}
/**
 * إيقاف المحرك الاستباقي لمستأجر
 */
export function stopProactiveEngine(tenantId) {
    const engine = activeEngines.get(tenantId);
    if (!engine)
        return;
    clearInterval(engine.intervalId);
    engine.isRunning = false;
    activeEngines.delete(tenantId);
    log.info({ tenantId }, 'Proactive engine stopped');
}
/**
 * إيقاف جميع المحركات الاستباقية
 */
export function stopAllProactiveEngines() {
    for (const [tenantId] of activeEngines) {
        stopProactiveEngine(tenantId);
    }
    log.info('All proactive engines stopped');
}
// ─── Core Check Logic ────────────────────────────────────────────────
async function runProactiveChecks(tenantId) {
    const hour = getSaudiHour();
    const day = getSaudiDay();
    const today = todayKey();
    const runs = lastRuns[tenantId] ?? {};
    // لا نعمل بالليل (11 PM - 7 AM)
    if (hour >= 23 || hour < 7)
        return;
    // ─── التقرير اليومي — 9 AM Saudi time ───
    if (hour === 9 && runs[`daily-${today}`] === undefined) {
        runs[`daily-${today}`] = Date.now();
        lastRuns[tenantId] = runs;
        await sendDailyReport(tenantId);
    }
    // ─── التقرير الأسبوعي — Sunday 9 AM Saudi time ───
    if (day === 0 && hour === 9 && runs[`weekly-${today}`] === undefined) {
        runs[`weekly-${today}`] = Date.now();
        lastRuns[tenantId] = runs;
        await sendWeeklyReport(tenantId);
    }
    // ─── متابعة العملاء — مرة كل يوم الساعة 10 صباحاً ───
    if (hour === 10 && runs[`followup-${today}`] === undefined) {
        runs[`followup-${today}`] = Date.now();
        lastRuns[tenantId] = runs;
        await checkStaleCustomers(tenantId);
    }
}
// ─── Daily Report ────────────────────────────────────────────────────
async function sendDailyReport(tenantId) {
    try {
        const tenant = await getTenantById(tenantId);
        if (!tenant) {
            log.debug({ tenantId }, 'Skipping daily report — tenant not found');
            return;
        }
        log.info({ tenantId }, 'Generating daily report');
        const reportMarkdown = await generateDailyReport(tenantId);
        const reportText = `📊 *التقرير اليومي*\n\n${reportMarkdown.slice(0, 4000)}`;
        // (v3.0.1) ALWAYS surface in the dashboard chat thread first — the WA
        // path is best-effort because most customers haven't paired WA yet.
        // Previously this only went to WA and the report was invisible.
        await pushDailyReportToChat(tenantId, reportText);
        // Best-effort WA delivery
        if (tenant.owner_phone) {
            try {
                await whatsappClient.sendText(tenant.owner_phone, reportText);
            }
            catch (err) {
                log.warn({ tenantId, error: err.message }, 'WA delivery of daily report failed (chat bubble still posted)');
            }
        }
        log.info({ tenantId }, 'Daily report sent');
    }
    catch (err) {
        log.error({ tenantId, error: err instanceof Error ? err.message : String(err) }, 'Failed to send daily report');
    }
}
/** Insert the daily report into the owner's chat thread with session_id
 * `daily_report:<date>` so the dashboard's recent-message poll renders it
 * with a 📊 source badge + iPhone-style notification. */
async function pushDailyReportToChat(tenantId, content) {
    const { v4: uuidv4 } = await import('uuid');
    const recent = await supabase
        .from('customers')
        .select('id')
        .eq('tenant_id', tenantId)
        .order('last_contact', { ascending: false })
        .limit(1);
    const customerId = recent.data?.[0]?.id;
    if (!customerId) {
        log.debug({ tenantId }, 'pushDailyReportToChat: no customer to attach to — skipping');
        return;
    }
    const dateKey = new Date().toISOString().slice(0, 10);
    await supabase.from('messages').insert({
        id: uuidv4(),
        tenant_id: tenantId,
        customer_id: customerId,
        session_id: `daily_report:${dateKey}`,
        direction: 'outbound',
        type: 'text',
        content,
        delivery_status: 'sent',
        created_at: new Date().toISOString(),
    });
    await supabase
        .from('customers')
        .update({ last_contact: new Date().toISOString() })
        .eq('id', customerId);
}
// ─── Weekly Report ───────────────────────────────────────────────────
async function sendWeeklyReport(tenantId) {
    try {
        const tenant = await getTenantById(tenantId);
        if (!tenant || !tenant.owner_phone)
            return;
        log.info({ tenantId }, 'Generating weekly report');
        const reportMarkdown = await generateWeeklyReport(tenantId);
        // Try to generate PDF for the weekly report
        try {
            const pdfPath = await generateReport(tenantId, 'weekly', {
                title: 'التقرير الأسبوعي',
                sections: [{ title: 'ملخص', content: reportMarkdown }],
            });
            await whatsappClient.sendDocument(tenant.owner_phone, pdfPath, `weekly-report-${todayKey()}.pdf`, '📈 التقرير الأسبوعي — المؤسس');
        }
        catch {
            // Fallback to text
            await whatsappClient.sendText(tenant.owner_phone, `📈 *التقرير الأسبوعي*\n\n${reportMarkdown.slice(0, 4000)}`);
        }
        log.info({ tenantId }, 'Weekly report sent');
    }
    catch (err) {
        log.error({ tenantId, error: err instanceof Error ? err.message : String(err) }, 'Failed to send weekly report');
    }
}
// ─── Stale Customer Follow-ups ───────────────────────────────────────
async function checkStaleCustomers(tenantId) {
    try {
        const tenant = await getTenantById(tenantId);
        if (!tenant || !tenant.owner_phone)
            return;
        // العملاء اللي ما تواصلنا معهم 3+ أيام
        const threeDaysAgo = new Date();
        threeDaysAgo.setDate(threeDaysAgo.getDate() - 3);
        const { data: staleCustomers, error } = await supabase
            .from('customers')
            .select('id, name, phone, last_seen_at, message_count')
            .eq('tenant_id', tenantId)
            .lt('last_seen_at', threeDaysAgo.toISOString())
            .gte('message_count', 2) // فقط العملاء اللي تفاعلوا أكثر من مرة
            .order('last_seen_at', { ascending: true })
            .limit(10);
        if (error || !staleCustomers?.length)
            return;
        // إرسال تذكير لصاحب العمل
        const lines = staleCustomers.map(c => {
            const name = c.name ?? c.phone;
            const daysSince = Math.floor((Date.now() - new Date(c.last_seen_at).getTime()) / (1000 * 60 * 60 * 24));
            return `• ${name} — آخر تواصل قبل ${daysSince} يوم (${c.message_count} رسائل)`;
        });
        const message = [
            '🔔 *تذكير متابعة العملاء*',
            '',
            `عندك ${staleCustomers.length} عملاء ما تواصلت معهم من فترة:`,
            '',
            ...lines,
            '',
            '💡 تقدر ترسل لهم متابعة بسيطة عشان تحافظ على العلاقة.',
        ].join('\n');
        await whatsappClient.sendText(tenant.owner_phone, message);
        log.info({ tenantId, staleCount: staleCustomers.length }, 'Follow-up reminder sent');
    }
    catch (err) {
        log.error({ tenantId, error: err instanceof Error ? err.message : String(err) }, 'Stale customer check failed');
    }
}
// ─── Status ──────────────────────────────────────────────────────────
export function getProactiveStatus() {
    const status = {};
    for (const [tenantId, engine] of activeEngines) {
        status[tenantId] = { isRunning: engine.isRunning };
    }
    return status;
}
//# sourceMappingURL=proactive.js.map