import { NextRequest, NextResponse } from 'next/server';
import { getDatabase, Activity } from '@/lib/db';
import { requireRole } from '@/lib/auth';
import { logger } from '@/lib/logger';

/**
 * GET /api/activities - Get activity stream or stats
 * Query params: type, actor, entity_type, limit, offset, since, hours (for stats)
 */
export async function GET(request: NextRequest) {
  const auth = requireRole(request, 'viewer')
  if ('error' in auth) return NextResponse.json({ error: auth.error }, { status: auth.status })

  try {
    const { searchParams, pathname } = new URL(request.url);
    const workspaceId = auth.user.workspace_id ?? 1;
    
    // Route to stats endpoint if requested
    if (pathname.endsWith('/stats') || searchParams.has('stats')) {
      return handleStatsRequest(request, workspaceId);
    }
    
    // Default activities endpoint
    return handleActivitiesRequest(request, workspaceId);
  } catch (error) {
    logger.error({ err: error }, 'GET /api/activities error');
    return NextResponse.json({ error: 'Failed to process request' }, { status: 500 });
  }
}

/**
 * Handle regular activities request
 */
async function handleActivitiesRequest(request: NextRequest, workspaceId: number) {
  try {
    const db = getDatabase();
    const { searchParams } = new URL(request.url);
    
    // Parse query parameters
    const type = searchParams.get('type');
    const actor = searchParams.get('actor');
    const entity_type = searchParams.get('entity_type');
    const limit = Math.min(parseInt(searchParams.get('limit') || '50'), 500);
    const offset = parseInt(searchParams.get('offset') || '0');
    const since = searchParams.get('since'); // Unix timestamp for real-time updates
    
    // Build dynamic query
    let query = 'SELECT * FROM activities WHERE workspace_id = ?';
    const params: any[] = [workspaceId];
    
    if (type) {
      const types = type.split(',').map(t => t.trim()).filter(Boolean);
      if (types.length === 1) {
        query += ' AND type = ?';
        params.push(types[0]);
      } else if (types.length > 1) {
        query += ` AND type IN (${types.map(() => '?').join(',')})`;
        params.push(...types);
      }
    }
    
    if (actor) {
      query += ' AND actor = ?';
      params.push(actor);
    }
    
    if (entity_type) {
      query += ' AND entity_type = ?';
      params.push(entity_type);
    }
    
    if (since) {
      query += ' AND created_at > ?';
      params.push(parseInt(since));
    }
    
    query += ' ORDER BY created_at DESC LIMIT ? OFFSET ?';
    params.push(limit, offset);
    
    const stmt = db.prepare(query);
    const activities = stmt.all(...params) as Activity[];
    
    // Prepare entity detail statements once (avoids N+1)
    const taskDetailStmt = db.prepare('SELECT id, title, status FROM tasks WHERE id = ? AND workspace_id = ?');
    const agentDetailStmt = db.prepare('SELECT id, name, role, status FROM agents WHERE id = ? AND workspace_id = ?');
    const commentDetailStmt = db.prepare(`
      SELECT c.id, c.content, c.task_id, t.title as task_title
      FROM comments c
      LEFT JOIN tasks t ON c.task_id = t.id
      WHERE c.id = ? AND c.workspace_id = ? AND t.workspace_id = ?
    `);

    // Parse JSON data field and enhance with related entity data
    const enhancedActivities = activities.map(activity => {
      let entityDetails = null;

      try {
        switch (activity.entity_type) {
          case 'task': {
            const task = taskDetailStmt.get(activity.entity_id, workspaceId) as any;
            if (task) {
              entityDetails = { type: 'task', ...task };
            }
            break;
          }
          case 'agent': {
            const agent = agentDetailStmt.get(activity.entity_id, workspaceId) as any;
            if (agent) {
              entityDetails = { type: 'agent', ...agent };
            }
            break;
          }
          case 'comment': {
            const comment = commentDetailStmt.get(activity.entity_id, workspaceId, workspaceId) as any;
            if (comment) {
              entityDetails = {
                type: 'comment',
                ...comment,
                content_preview: comment.content?.substring(0, 100) || ''
              };
            }
            break;
          }
        }
      } catch (error) {
        logger.warn({ err: error, activityId: activity.id }, 'Failed to fetch entity details for activity');
      }

      return {
        ...activity,
        data: activity.data ? JSON.parse(activity.data) : null,
        entity: entityDetails
      };
    });
    
    // Get total count for pagination
    let countQuery = 'SELECT COUNT(*) as total FROM activities WHERE workspace_id = ?';
    const countParams: any[] = [workspaceId];
    
    if (type) {
      const types = type.split(',').map(t => t.trim()).filter(Boolean);
      if (types.length === 1) {
        countQuery += ' AND type = ?';
        countParams.push(types[0]);
      } else if (types.length > 1) {
        countQuery += ` AND type IN (${types.map(() => '?').join(',')})`;
        countParams.push(...types);
      }
    }
    
    if (actor) {
      countQuery += ' AND actor = ?';
      countParams.push(actor);
    }
    
    if (entity_type) {
      countQuery += ' AND entity_type = ?';
      countParams.push(entity_type);
    }
    
    if (since) {
      countQuery += ' AND created_at > ?';
      countParams.push(parseInt(since));
    }
    
    const countResult = db.prepare(countQuery).get(...countParams) as { total: number };
    
    return NextResponse.json({ 
      activities: enhancedActivities,
      total: countResult.total,
      hasMore: offset + activities.length < countResult.total
    });
  } catch (error) {
    logger.error({ err: error }, 'GET /api/activities (activities) error');
    return NextResponse.json({ error: 'Failed to fetch activities' }, { status: 500 });
  }
}

/**
 * Handle stats request
 */
async function handleStatsRequest(request: NextRequest, workspaceId: number) {
  try {
    const db = getDatabase();
    const { searchParams } = new URL(request.url);
    
    // Parse timeframe parameter (defaults to 24 hours)
    const hours = parseInt(searchParams.get('hours') || '24');
    const since = Math.floor(Date.now() / 1000) - (hours * 3600);
    
    // Get activity counts by type
    const activityStats = db.prepare(`
      SELECT 
        type,
        COUNT(*) as count
      FROM activities 
      WHERE created_at > ? AND workspace_id = ?
      GROUP BY type
      ORDER BY count DESC
    `).all(since, workspaceId) as { type: string; count: number }[];
    
    // Get most active actors
    const activeActors = db.prepare(`
      SELECT 
        actor,
        COUNT(*) as activity_count
      FROM activities 
      WHERE created_at > ? AND workspace_id = ?
      GROUP BY actor
      ORDER BY activity_count DESC
      LIMIT 10
    `).all(since, workspaceId) as { actor: string; activity_count: number }[];
    
    // Get activity timeline (hourly buckets)
    const timeline = db.prepare(`
      SELECT 
        (created_at / 3600) * 3600 as hour_bucket,
        COUNT(*) as count
      FROM activities 
      WHERE created_at > ? AND workspace_id = ?
      GROUP BY hour_bucket
      ORDER BY hour_bucket ASC
    `).all(since, workspaceId) as { hour_bucket: number; count: number }[];
    
    return NextResponse.json({
      timeframe: `${hours} hours`,
      activityByType: activityStats,
      topActors: activeActors,
      timeline: timeline.map(item => ({
        timestamp: item.hour_bucket,
        count: item.count,
        hour: new Date(item.hour_bucket * 1000).toISOString()
      }))
    });
  } catch (error) {
    logger.error({ err: error }, 'GET /api/activities (stats) error');
    return NextResponse.json({ error: 'Failed to fetch activity stats' }, { status: 500 });
  }
}
