import { Router, Request } from 'express';
import pool from '../db';

const router = Router();

/** Strip metadata wrappers and telegram prefixes from message content */
function cleanContent(content: string): string | null {
  if (!content) return null;
  let text = content.trim();

  if (text.startsWith('System:') || text.startsWith('Pre-compaction') ||
      /^\[(Mon|Tue|Wed|Thu|Fri|Sat|Sun) /.test(text)) {
    return null;
  }

  if (text.startsWith('[media attached')) return '[sent image/media]';

  if (text.startsWith('[Queued messages')) {
    const chunks = text.split(/---\s*\nQueued #\d+\s*\n/);
    for (const chunk of chunks.slice(1)) {
      const clean = cleanContent(chunk.trim());
      if (clean) return clean;
    }
    return null;
  }

  if (text.startsWith('Conversation info')) {
    const blocks = [...text.matchAll(/```/g)];
    if (blocks.length >= 2) {
      const lastClose = (blocks[blocks.length - 1] as any).index + 3;
      text = text.slice(lastClose).trim();
    }
    if (!text) return null;
  }

  const tgMatch = text.match(/^\[Telegram \S+ id:\S+[^\]]*\]\s*.+?\(\d+\):\s*([\s\S]*)/);
  if (tgMatch) text = tgMatch[1].trim();

  text = text.replace(/\[message_id:\s*\d+\]/g, '').trim();
  text = text.replace(/\[Replying to \S+ id:\d+\]\s*/g, '').trim();
  text = text.split('\n').filter(l => l.trim()).join('\n');

  return text || null;
}

function extractSender(content: string): string | null {
  const m = content.match(/Sender \(untrusted metadata\):\s*```json\s*(\{[^}]+\})\s*```/);
  if (m) {
    try {
      const s = JSON.parse(m[1]);
      const name = s.name || s.label || '';
      const uname = s.username || '';
      if (name && !['Group', 'GroupAnonymousBot'].includes(name)) {
        return uname && uname !== 'GroupAnonymousBot' ? `${name} (@${uname})` : name;
      }
      if (uname && uname !== 'GroupAnonymousBot') return `@${uname}`;
    } catch {}
  }
  return null;
}

// GET /api/queries/live — recent queries across all agents with expandable responses
router.get('/live', async (req: Request, res) => {
  try {
    const page = Math.max(1, parseInt(req.query.page as string) || 1);
    const limit = Math.min(200, parseInt(req.query.limit as string) || 100);
    const offset = (page - 1) * limit;
    const agent = req.query.agent as string;
    const since = req.query.since as string;
    const search = req.query.search as string;

    let conditions = `s.agent IN ('sportsclaw','cryptoclaw','main')
      AND m.role = 'user' AND m.content_type = 'text' AND m.tool_name IS NULL
      AND m.content IS NOT NULL AND LENGTH(m.content) > 0`;
    const params: any[] = [];
    let paramIdx = 1;

    if (agent) {
      conditions += ` AND s.agent = $${paramIdx}`;
      params.push(agent);
      paramIdx++;
    }

    if (since) {
      conditions += ` AND m.timestamp > $${paramIdx}`;
      params.push(since);
      paramIdx++;
    }

    if (search) {
      conditions += ` AND to_tsvector('english', m.content) @@ plainto_tsquery('english', $${paramIdx})`;
      params.push(search);
      paramIdx++;
    }

    const countQ = `SELECT COUNT(*) FROM crm_messages m JOIN crm_sessions s ON m.session_id = s.id WHERE ${conditions}`;
    const dataQ = `
      SELECT m.id, m.timestamp, m.content, m.session_id, s.agent,
             COALESCE(NULLIF(c.username,''), c.display_name, '') as who,
             COALESCE(c.display_name, '') as display,
             COALESCE(c.plan, '') as plan,
             CASE WHEN s.chat_type = 'group' THEN COALESCE(s.group_name,'group') ELSE 'DM' END as channel,
             EXISTS (
               SELECT 1 FROM crm_messages r
               WHERE r.session_id = m.session_id
                 AND r.timestamp > m.timestamp
                 AND r.timestamp < (m.timestamp + interval '5 minutes')
                 AND r.role = 'assistant'
                 AND r.content_type = 'text'
                 AND r.content IS NOT NULL AND LENGTH(r.content) > 0
             ) AS has_response
      FROM crm_messages m
      JOIN crm_sessions s ON m.session_id = s.id
      LEFT JOIN crm_contacts c ON m.contact_id = c.id
      WHERE ${conditions}
      ORDER BY m.timestamp DESC
      LIMIT $${paramIdx} OFFSET $${paramIdx + 1}
    `;

    const [countResult, dataResult] = await Promise.all([
      pool.query(countQ, params),
      pool.query(dataQ, [...params, limit, offset]),
    ]);

    // Clean and dedup
    const queries: any[] = [];
    const seen = new Set<string>();
    for (const row of dataResult.rows) {
      const text = cleanContent(row.content);
      if (!text) continue;
      const key = text.slice(0, 100).toLowerCase().trim();
      if (seen.has(key)) continue;
      seen.add(key);

      let name = row.who || row.display || extractSender(row.content) || 'unknown';
      if (row.display && row.display !== row.who && row.who) {
        name = `${row.display} (@${row.who})`;
      }

      queries.push({
        id: row.id,
        timestamp: row.timestamp,
        content: text,
        agent: row.agent,
        channel: row.channel,
        user: name,
        plan: row.plan,
        session_id: row.session_id,
        has_response: row.has_response,
      });
    }

    res.json({
      queries,
      total: parseInt(countResult.rows[0].count),
      page, limit,
    });
  } catch (err: any) {
    console.error('Live queries error:', err);
    res.status(500).json({ error: err.message });
  }
});

// GET /api/queries/:id/response — get the bot response(s) following a user query
router.get('/:id/response', async (req, res) => {
  try {
    const { id } = req.params;

    // Get the query message to find its session and timestamp
    const msgResult = await pool.query(
      `SELECT m.session_id, m.timestamp, m.contact_id FROM crm_messages m WHERE m.id = $1`, [id]
    );
    if (msgResult.rows.length === 0) {
      res.status(404).json({ error: 'Message not found' });
      return;
    }

    const { session_id, timestamp } = msgResult.rows[0];

    // Get the next assistant text messages after this query (up to 3, within 5 min)
    const responseResult = await pool.query(`
      SELECT m.id, m.role, m.content, m.content_type, m.timestamp
      FROM crm_messages m
      WHERE m.session_id = $1
        AND m.timestamp > $2
        AND m.timestamp < ($2::timestamptz + interval '5 minutes')
        AND m.role = 'assistant'
        AND m.content_type = 'text'
        AND m.content IS NOT NULL AND LENGTH(m.content) > 0
      ORDER BY m.timestamp ASC
      LIMIT 3
    `, [session_id, timestamp]);

    // Clean assistant responses too (strip tool JSON etc)
    const responses = responseResult.rows.map(r => ({
      id: r.id,
      content: r.content,
      timestamp: r.timestamp,
    }));

    res.json({ responses });
  } catch (err: any) {
    console.error('Query response error:', err);
    res.status(500).json({ error: err.message });
  }
});

export default router;
