import { NextResponse } from 'next/server';
import { getAdminAuth, getAdminDb } from '@/lib/firebase/admin';
import { FieldValue } from 'firebase-admin/firestore';

/**
 * Associate existing sessions with a project when GitHub is connected
 * Matches sessions by:
 * 1. githubRepo field (from Cursor extension)
 * 2. workspacePath (if repo name matches)
 */
export async function POST(
  request: Request,
  { params }: { params: Promise<{ projectId: string }> }
) {
  try {
    const { projectId } = await params;
    
    const authHeader = request.headers.get('Authorization');
    if (!authHeader?.startsWith('Bearer ')) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const idToken = authHeader.split('Bearer ')[1];
    const adminAuth = getAdminAuth();
    const adminDb = getAdminDb();

    let userId: string;
    try {
      const decodedToken = await adminAuth.verifyIdToken(idToken);
      userId = decodedToken.uid;
    } catch (error) {
      return NextResponse.json({ error: 'Invalid token' }, { status: 401 });
    }

    const { githubRepo, githubRepoUrl } = await request.json();

    if (!githubRepo) {
      return NextResponse.json(
        { error: 'githubRepo is required' },
        { status: 400 }
      );
    }

    // Verify project belongs to user
    const projectDoc = await adminDb.collection('projects').doc(projectId).get();
    if (!projectDoc.exists || projectDoc.data()?.userId !== userId) {
      return NextResponse.json(
        { error: 'Project not found or unauthorized' },
        { status: 403 }
      );
    }

    const projectData = projectDoc.data();
    const projectWorkspacePath = projectData?.workspacePath;

    console.log(`[Associate GitHub Sessions] Project: ${projectId}`);
    console.log(`[Associate GitHub Sessions] GitHub repo: ${githubRepo}`);
    console.log(`[Associate GitHub Sessions] Project workspace path: ${projectWorkspacePath || 'not set'}`);
    console.log(`[Associate GitHub Sessions] User ID: ${userId}`);

    // Strategy 1: Match by exact githubRepo field in sessions
    // (This requires the Cursor extension to send githubRepo with sessions)
    const sessionsSnapshot1 = await adminDb
      .collection('sessions')
      .where('userId', '==', userId)
      .where('githubRepo', '==', githubRepo)
      .where('needsProjectAssociation', '==', true)
      .get();

    console.log(`[Associate GitHub Sessions] Found ${sessionsSnapshot1.size} sessions with exact githubRepo match`);

    // Strategy 2: Match by exact workspacePath (if project has one set)
    let matchedByPath: any[] = [];
    
    if (projectWorkspacePath) {
      console.log(`[Associate GitHub Sessions] Strategy 2A: Exact workspace path match`);
      console.log(`[Associate GitHub Sessions] Looking for sessions from: ${projectWorkspacePath}`);
      
      const pathMatchSnapshot = await adminDb
        .collection('sessions')
        .where('userId', '==', userId)
        .where('workspacePath', '==', projectWorkspacePath)
        .where('needsProjectAssociation', '==', true)
        .get();
      
      matchedByPath = pathMatchSnapshot.docs;
      console.log(`[Associate GitHub Sessions] Found ${matchedByPath.length} sessions with exact workspace path match`);
    } else {
      // Fallback: Match by repo name (less reliable but better than nothing)
      console.log(`[Associate GitHub Sessions] Strategy 2B: Fuzzy match by repo folder name (project has no workspace path set)`);
      const repoName = githubRepo.split('/')[1]; // Extract "my-app" from "username/my-app"
      console.log(`[Associate GitHub Sessions] Looking for folders ending with: ${repoName}`);
      
      const allUnassociatedSessions = await adminDb
        .collection('sessions')
        .where('userId', '==', userId)
        .where('needsProjectAssociation', '==', true)
        .get();

      console.log(`[Associate GitHub Sessions] Total unassociated sessions for user: ${allUnassociatedSessions.size}`);

      matchedByPath = allUnassociatedSessions.docs.filter(doc => {
        const workspacePath = doc.data().workspacePath;
        if (!workspacePath) return false;
        
        const pathSegments = workspacePath.split('/');
        const lastSegment = pathSegments[pathSegments.length - 1];
        const matches = lastSegment === repoName;
        
        if (matches) {
          console.log(`[Associate GitHub Sessions] ✅ Fuzzy match: ${workspacePath} ends with ${repoName}`);
        }
        
        return matches;
      });

      console.log(`[Associate GitHub Sessions] Found ${matchedByPath.length} sessions with fuzzy folder name match`);
      
      // Debug: Log some example workspace paths to help diagnose
      if (matchedByPath.length === 0 && allUnassociatedSessions.size > 0) {
        console.log(`[Associate GitHub Sessions] Debug - Example workspace paths in unassociated sessions:`);
        allUnassociatedSessions.docs.slice(0, 5).forEach(doc => {
          const path = doc.data().workspacePath;
          const folder = path ? path.split('/').pop() : 'null';
          console.log(`  - ${path} (folder: ${folder})`);
        });
        console.log(`[Associate GitHub Sessions] Tip: Set project.workspacePath for accurate matching`);
      }
    }

    // Combine both strategies (deduplicate by session ID)
    const allMatchedSessions = new Map();
    
    // Add exact matches
    sessionsSnapshot1.docs.forEach(doc => {
      allMatchedSessions.set(doc.id, doc);
    });
    
    // Add path matches
    matchedByPath.forEach(doc => {
      allMatchedSessions.set(doc.id, doc);
    });

    // Batch update all matched sessions
    if (allMatchedSessions.size > 0) {
      const batch = adminDb.batch();
      let count = 0;

      allMatchedSessions.forEach((doc) => {
        batch.update(doc.ref, {
          projectId,
          needsProjectAssociation: false,
          updatedAt: FieldValue.serverTimestamp(),
        });
        count++;
      });

      await batch.commit();

      console.log(`[Associate GitHub Sessions] Successfully associated ${count} sessions with project ${projectId}`);

      return NextResponse.json({
        success: true,
        sessionsAssociated: count,
        message: `Found and linked ${count} existing chat sessions from this repository`,
        details: {
          exactMatches: sessionsSnapshot1.size,
          pathMatches: matchedByPath.length,
        }
      });
    }

    return NextResponse.json({
      success: true,
      sessionsAssociated: 0,
      message: 'No matching sessions found for this repository',
    });

  } catch (error) {
    console.error('[Associate GitHub Sessions] Error:', error);
    return NextResponse.json(
      {
        error: 'Failed to associate sessions',
        details: error instanceof Error ? error.message : String(error),
      },
      { status: 500 }
    );
  }
}

