#!/usr/bin/env node
'use strict';
const path = require('path');
const brain = require(path.resolve(__dirname, '..', '..', '..', 'brain'));

// initDb/closeDb only when running standalone (CLI mode)
// When called from skill-planner, brain is already initialized
const _standaloneMode = require.main === module;
if (_standaloneMode) brain.initDb();
const db = brain.getDb();

async function main() {
  const now = new Date();
  const alerts = [];

  // 1. Calendar events in the next 15 minutes
  try {
    const { getCalendarEvents } = require(path.resolve(__dirname, '..', '..', '..', 'tools', 'local-tools'));
    const { events } = await getCalendarEvents({ days_ahead: 0 });
    const soonMs = 15 * 60 * 1000;
    for (const evt of events) {
      const start = new Date(evt.start);
      if (isNaN(start)) continue;
      const diff = start.getTime() - now.getTime();
      if (diff > 0 && diff <= soonMs) {
        alerts.push({
          type: 'calendar_soon',
          urgency: 'critical',
          title: `Meeting in ${Math.round(diff / 60000)}min: ${evt.title}`,
          data: { event: evt.title, start: evt.start, attendees: evt.attendees?.slice(0, 5) },
        });
      }
    }
  } catch (err) {
    // Calendar unavailable -- skip silently
  }

  // 2. Direct @mentions in recent Slack messages (last 30 minutes)
  try {
    const ownerFirst = (process.env.WALLE_OWNER_NAME || 'owner').split(' ')[0].replace(/['"*()]/g, '');
    const hasFts = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='memories_fts'").get();
    if (hasFts && ownerFirst.length >= 2) {
      const cutoff = new Date(now.getTime() - 30 * 60000).toISOString();
      const mentions = db.prepare(`
        SELECT m.content, m.source_channel, m.participants, m.timestamp
        FROM memories_fts f
        JOIN memories m ON m.rowid = f.rowid
        WHERE memories_fts MATCH ?
          AND m.source = 'slack' AND m.direction = 'inbound'
          AND m.timestamp > ?
        ORDER BY m.timestamp DESC
        LIMIT 5
      `).all(ownerFirst, cutoff);

      for (const m of mentions) {
        alerts.push({
          type: 'mention',
          urgency: 'today',
          title: `@mention from ${extractName(m.participants)} in ${m.source_channel || 'Slack'}`,
          data: { content: (m.content || '').slice(0, 200), channel: m.source_channel, timestamp: m.timestamp },
        });
      }
    }
  } catch {}

  // 3. Tasks due within 1 hour
  try {
    const tasks = brain.listTasks({ status: 'pending', limit: 20 });
    const oneHourMs = 60 * 60 * 1000;
    for (const t of tasks) {
      if (!t.due_at) continue;
      const due = new Date(t.due_at);
      const diff = due.getTime() - now.getTime();
      if (diff > 0 && diff <= oneHourMs) {
        alerts.push({
          type: 'deadline',
          urgency: diff <= 15 * 60000 ? 'critical' : 'today',
          title: `Due in ${Math.round(diff / 60000)}min: ${t.title}`,
          data: { task_id: t.id, title: t.title, due_at: t.due_at },
        });
      }
    }
  } catch {}

  // 4. Failed tasks needing attention
  try {
    const failed = brain.listTasks({ status: 'failed', limit: 5 });
    for (const t of failed) {
      alerts.push({
        type: 'failed_task',
        urgency: 'today',
        title: `Failed: ${t.title} -- ${(t.error || 'unknown error').slice(0, 80)}`,
        data: { task_id: t.id, title: t.title, error: t.error },
      });
    }
  } catch {}

  // 5. Service health alerts (auth failures, disabled skills, updates)
  try {
    const { getServiceAlerts } = require(path.resolve(__dirname, '..', '..', 'skill-planner'));
    for (const alert of getServiceAlerts()) {
      alerts.push({
        type: 'service_health',
        urgency: alert.type === 'auth_expired' ? 'critical' : 'today',
        title: alert.message,
        data: { service: alert.service, action_url: alert.action_url, created_at: alert.created_at },
      });
    }
  } catch {}

  // 6. Urgent briefing items
  try {
    const urgent = db.prepare(`
      SELECT * FROM briefing_items
      WHERE status = 'new' AND urgency IN ('critical', 'today')
        AND (snooze_until IS NULL OR snooze_until < datetime('now'))
      ORDER BY urgency, created_at DESC LIMIT 5
    `).all();
    for (const item of urgent) {
      alerts.push({
        type: 'briefing_item',
        urgency: item.urgency,
        title: item.title,
        data: { id: item.id, category: item.category, owner: item.owner },
      });
    }
  } catch {}

  // Output
  if (alerts.length === 0) {
    console.log('No alerts.');
  } else {
    console.log(`${alerts.length} alert(s) found:`);
    for (const a of alerts) {
      console.log(`[${a.urgency}] ${a.title}`);
    }
    // Structured output for the task runner
    console.log('<!-- BRIEFING_ITEMS');
    console.log(JSON.stringify(alerts.map(a => ({
      title: a.title,
      category: a.type,
      urgency: a.urgency,
      context: a.data,
    })), null, 2));
    console.log('-->');
  }

  if (_standaloneMode) brain.closeDb();
}

function extractName(participants) {
  if (!participants) return 'someone';
  const name = participants.split(',')[0].trim().replace(/^\*+|\*+$/g, '');
  return name.split(' ')[0] || name || 'someone';
}

// Export for skill-planner; also run directly when invoked as CLI script
module.exports = { run: main };

if (require.main === module) {
  main().catch(err => {
    console.error('[proactive-alerts] Error:', err.message);
    process.exit(1);
  });
}
