import { NextRequest, NextResponse } from 'next/server';
import { adminDb } from '@/lib/firebase/admin';

export async function POST(request: NextRequest) {
  try {
    const projectId = request.nextUrl.searchParams.get('projectId');
    const sessionGapMinutes = parseInt(request.nextUrl.searchParams.get('gap') || '30'); // 30 min default
    
    if (!projectId) {
      return NextResponse.json({ error: 'Missing projectId' }, { status: 400 });
    }

    // Get all conversations sorted by time
    const conversationsSnapshot = await adminDb
      .collection('projects')
      .doc(projectId)
      .collection('cursorConversations')
      .orderBy('createdAt', 'asc')
      .get();

    const conversations = conversationsSnapshot.docs.map((doc: FirebaseFirestore.QueryDocumentSnapshot) => {
      const data = doc.data();
      return {
        id: doc.id,
        ref: doc.ref,
        name: data.name,
        createdAt: new Date(data.createdAt),
        relevanceScore: data.relevanceScore || 0
      };
    });

    // Step 1: Group by date
    const conversationsByDate: Record<string, typeof conversations> = {};
    
    for (const conv of conversations) {
      const dateKey = conv.createdAt.toISOString().split('T')[0]; // YYYY-MM-DD
      if (!conversationsByDate[dateKey]) {
        conversationsByDate[dateKey] = [];
      }
      conversationsByDate[dateKey].push(conv);
    }

    // Step 2: Within each date, create sessions based on time gaps
    const sessions: any[] = [];
    let sessionId = 0;

    for (const [date, dayConversations] of Object.entries(conversationsByDate)) {
      let currentSession: any = null;

      for (const conv of dayConversations) {
        if (!currentSession) {
          // Start first session of the day
          sessionId++;
          currentSession = {
            sessionId,
            date,
            startTime: conv.createdAt,
            endTime: conv.createdAt,
            conversations: [conv]
          };
        } else {
          // Check time gap from last conversation
          const gapMs = conv.createdAt.getTime() - currentSession.endTime.getTime();
          const gapMinutes = gapMs / (1000 * 60);

          if (gapMinutes <= sessionGapMinutes) {
            // Same session
            currentSession.conversations.push(conv);
            currentSession.endTime = conv.createdAt;
          } else {
            // New session - close current and start new
            sessions.push(currentSession);
            sessionId++;
            currentSession = {
              sessionId,
              date,
              startTime: conv.createdAt,
              endTime: conv.createdAt,
              conversations: [conv]
            };
          }
        }
      }

      // Add last session of the day
      if (currentSession) {
        sessions.push(currentSession);
      }
    }

    // Step 3: Analyze each session and determine project
    const projectKeywords = ['vibn', 'extension', 'collector', 'cursor-monitor'];
    const excludeKeywords = ['nhl', 'hockey', 'market', 'transaction'];

    const analyzedSessions = sessions.map(session => {
      const allNames = session.conversations.map((c: any) => c.name.toLowerCase()).join(' ');
      
      let projectTag = 'unknown';
      let confidence = 'low';
      
      // Check for strong exclude signals
      for (const keyword of excludeKeywords) {
        if (allNames.includes(keyword)) {
          projectTag = 'other';
          confidence = 'high';
          break;
        }
      }
      
      // If not excluded, check for vibn signals
      if (projectTag === 'unknown') {
        for (const keyword of projectKeywords) {
          if (allNames.includes(keyword)) {
            projectTag = 'vibn';
            confidence = 'high';
            break;
          }
        }
      }
      
      // If still unknown, check for generic "project" keyword
      if (projectTag === 'unknown' && allNames.includes('project')) {
        projectTag = 'vibn';
        confidence = 'medium';
      }

      return {
        ...session,
        projectTag,
        confidence,
        conversationCount: session.conversations.length
      };
    });

    // Step 4: Update Firestore with session tags
    const batch = adminDb.batch();
    let updateCount = 0;

    for (const session of analyzedSessions) {
      for (const conv of session.conversations) {
        batch.update(conv.ref, {
          sessionId: session.sessionId,
          sessionDate: session.date,
          sessionProject: session.projectTag,
          sessionConfidence: session.confidence
        });
        updateCount++;
      }
    }

    await batch.commit();

    // Return summary
    const summary = {
      totalConversations: conversations.length,
      totalSessions: sessions.length,
      sessionGapMinutes,
      projectBreakdown: {
        vibn: analyzedSessions.filter(s => s.projectTag === 'vibn').length,
        other: analyzedSessions.filter(s => s.projectTag === 'other').length,
        unknown: analyzedSessions.filter(s => s.projectTag === 'unknown').length
      },
      conversationBreakdown: {
        vibn: analyzedSessions.filter(s => s.projectTag === 'vibn').reduce((sum, s) => sum + s.conversationCount, 0),
        other: analyzedSessions.filter(s => s.projectTag === 'other').reduce((sum, s) => sum + s.conversationCount, 0),
        unknown: analyzedSessions.filter(s => s.projectTag === 'unknown').reduce((sum, s) => sum + s.conversationCount, 0)
      },
      sampleSessions: analyzedSessions.slice(0, 10).map(s => ({
        sessionId: s.sessionId,
        date: s.date,
        conversationCount: s.conversationCount,
        projectTag: s.projectTag,
        confidence: s.confidence,
        conversationNames: s.conversations.slice(0, 3).map((c: any) => c.name)
      }))
    };

    return NextResponse.json({
      success: true,
      updatedConversations: updateCount,
      ...summary
    });

  } catch (error) {
    console.error('Error tagging sessions:', error);
    return NextResponse.json(
      { error: 'Failed to tag sessions', details: error instanceof Error ? error.message : String(error) },
      { status: 500 }
    );
  }
}

