import { getDb } from './db.js';
function like(v){ return `%${String(v || '').toLowerCase()}%`; }
export function search(params = {}) {
  const db = getDb(); const rows = [];
  const cap = Math.min(Number(params.limit || 500), 500);
  const query = params.query ? like(params.query) : null;
  const targetScoped = Boolean(params.action_target_id || params.action_target_type);
  function push(source, sql, bind = []) {
    try { for (const r of db.prepare(sql).all(...bind)) rows.push({ source, ...r }); } catch {}
  }
  // audit_logs: support user_id, org_id, ip, action_target_id, action_target_type filters
  const auditWhere = ['1=1'];
  const auditBind = [];
  if (params.project_id) { auditWhere.push('project_id = ?'); auditBind.push(params.project_id); }
  if (params.correlation_id) { auditWhere.push('correlation_id = ?'); auditBind.push(params.correlation_id); }
  if (params.user_id) { auditWhere.push('user_id = ?'); auditBind.push(params.user_id); }
  if (params.org_id) { auditWhere.push('org_id = ?'); auditBind.push(params.org_id); }
  if (params.ip) { auditWhere.push('ip = ?'); auditBind.push(params.ip); }
  if (params.action_target_id) { auditWhere.push('action_target_id = ?'); auditBind.push(params.action_target_id); }
  if (params.action_target_type) { auditWhere.push('action_target_type = ?'); auditBind.push(params.action_target_type); }
  if (query) { auditWhere.push("LOWER(COALESCE(summary,'') || COALESCE(type,'') || COALESCE(meta,'')) LIKE ?"); auditBind.push(query); }
  // Return user_id, org_id, ip so UI can display attribution columns
  push('audit_logs',
    `SELECT id, at AS time, type AS action, summary, status, NULL AS agent_id, project_id,
            NULL AS tool, correlation_id, user_id, org_id, ip
     FROM audit_logs WHERE ${auditWhere.join(' AND ')}`,
    auditBind);

  // Only audit_logs carry action_target_* columns. When a target filter is
  // present, do not mix in unrelated source rows that cannot honor it.
  if (!targetScoped) {

  // tool_egress: support agent_id, project_id, tool filters (no user_id/org_id/ip columns)
  const egressWhere = ['1=1'];
  const egressBind = [];
  if (params.project_id) { egressWhere.push('project_id = ?'); egressBind.push(params.project_id); }
  if (params.agent_id) { egressWhere.push('agent_id = ?'); egressBind.push(params.agent_id); }
  if (params.tool) { egressWhere.push('tool_name = ?'); egressBind.push(params.tool); }
  push('tool_egress',
    `SELECT id, at AS time, tool_name AS action, host AS summary,
            CASE WHEN error IS NULL THEN 'complete' ELSE 'error' END AS status,
            agent_id, project_id, tool_name AS tool, NULL AS correlation_id,
            NULL AS user_id, NULL AS org_id, NULL AS ip
     FROM tool_egress WHERE ${egressWhere.join(' AND ')}`,
    egressBind);

  // activity_log: support agent_id, project_id filters
  const actWhere = ['1=1'];
  const actBind = [];
  if (params.project_id) { actWhere.push('project_id = ?'); actBind.push(params.project_id); }
  if (params.agent_id) { actWhere.push('agent_id = ?'); actBind.push(params.agent_id); }
  push('activity_log',
    `SELECT id, created_at AS time, action, details_json AS summary, 'complete' AS status,
            agent_id, project_id, NULL AS tool, NULL AS correlation_id,
            NULL AS user_id, NULL AS org_id, NULL AS ip
     FROM activity_log WHERE ${actWhere.join(' AND ')}`,
    actBind);

  // artifacts: support agent_id, project_id filters
  const artWhere = ['1=1'];
  const artBind = [];
  if (params.project_id) { artWhere.push('project_id = ?'); artBind.push(params.project_id); }
  if (params.agent_id) { artWhere.push('agent_id = ?'); artBind.push(params.agent_id); }
  push('artifacts',
    `SELECT id, created_at AS time, kind AS action, title AS summary, 'complete' AS status,
            agent_id, project_id, NULL AS tool, NULL AS correlation_id,
            NULL AS user_id, NULL AS org_id, NULL AS ip
     FROM artifacts WHERE ${artWhere.join(' AND ')}`,
    artBind);

  }

  let filtered = rows.filter(r => {
    if (params.since && String(r.time || '') < params.since) return false;
    if (params.until && String(r.time || '') > params.until) return false;
    if (query && !String(`${r.action || ''} ${r.summary || ''}`).toLowerCase().includes(String(params.query).toLowerCase())) return false;
    return true;
  }).sort((a,b) => String(b.time || '').localeCompare(String(a.time || '')));
  const cursor = Number(params.cursor || 0);
  return { rows: filtered.slice(cursor, cursor + cap), next_cursor: filtered.length > cursor + cap ? String(cursor + cap) : null };
}
