import { NextRequest, NextResponse } from 'next/server';
import { adminDb } from '@/lib/firebase/admin';
import { getApiUrl } from '@/lib/utils/api-url';

// Types
interface WorkSession {
  sessionId: string;
  date: string;
  startTime: Date;
  endTime: Date;
  duration: number; // minutes
  messageCount: number;
  userMessages: number;
  aiMessages: number;
  topics: string[];
  filesWorkedOn: string[];
}

interface TimelineAnalysis {
  firstActivity: Date | null;
  lastActivity: Date | null;
  totalDays: number;
  activeDays: number;
  totalSessions: number;
  sessions: WorkSession[];
  velocity: {
    messagesPerDay: number;
    averageSessionLength: number;
    peakProductivityHours: number[];
  };
}

interface CostAnalysis {
  messageStats: {
    totalMessages: number;
    userMessages: number;
    aiMessages: number;
    avgMessageLength: number;
  };
  estimatedTokens: {
    input: number;
    output: number;
    total: number;
  };
  costs: {
    inputCost: number;
    outputCost: number;
    totalCost: number;
    currency: string;
  };
  model: string;
  pricing: {
    inputPer1M: number;
    outputPer1M: number;
  };
}

interface Feature {
  name: string;
  description: string;
  pages: string[];
  apis: string[];
  status: 'complete' | 'in-progress' | 'planned';
}

export async function POST(
  request: NextRequest,
  { params }: { params: Promise<{ projectId: string }> }
) {
  try {
    const { projectId } = await params;

    // 1. Load conversations from Firestore
    console.log(`🔍 Loading conversations for project ${projectId}...`);
    const conversationsSnapshot = await adminDb
      .collection('projects')
      .doc(projectId)
      .collection('cursorConversations')
      .get();

    if (conversationsSnapshot.empty) {
      return NextResponse.json({
        error: 'No conversations found for this project',
        suggestion: 'Import Cursor conversations first'
      }, { status: 404 });
    }

    const conversations = conversationsSnapshot.docs.map(doc => ({
      id: doc.id,
      ...doc.data()
    }));

    console.log(`✅ Found ${conversations.length} conversations`);

    // 2. Load all messages for each conversation
    let allMessages: any[] = [];
    for (const conv of conversations) {
      const messagesSnapshot = await adminDb
        .collection('projects')
        .doc(projectId)
        .collection('cursorConversations')
        .doc(conv.id)
        .collection('messages')
        .orderBy('createdAt', 'asc')
        .get();

      const messages = messagesSnapshot.docs.map(doc => ({
        ...doc.data(),
        conversationId: conv.id,
        conversationName: conv.name
      }));

      allMessages = allMessages.concat(messages);
    }

    console.log(`✅ Loaded ${allMessages.length} total messages`);

    // 3. Load extension activity data (files edited, sessions)
    let extensionActivity: any = null;
    try {
      const activitySnapshot = await adminDb
        .collection('sessions')
        .where('projectId', '==', projectId)
        .get();
      
      const extensionSessions = activitySnapshot.docs
        .map(doc => {
          const data = doc.data();
          return {
            startTime: data.startTime?.toDate?.() || data.startTime,
            endTime: data.endTime?.toDate?.() || data.endTime,
            filesModified: data.filesModified || [],
            conversationSummary: data.conversationSummary || ''
          };
        })
        .sort((a, b) => {
          const aTime = a.startTime ? new Date(a.startTime).getTime() : 0;
          const bTime = b.startTime ? new Date(b.startTime).getTime() : 0;
          return aTime - bTime;
        });

      // Analyze file activity
      const fileActivity: Record<string, number> = {};
      extensionSessions.forEach(session => {
        session.filesModified.forEach((file: string) => {
          fileActivity[file] = (fileActivity[file] || 0) + 1;
        });
      });

      const topFiles = Object.entries(fileActivity)
        .map(([file, count]) => ({ file, editCount: count }))
        .sort((a, b) => b.editCount - a.editCount)
        .slice(0, 20);

      extensionActivity = {
        totalSessions: extensionSessions.length,
        uniqueFilesEdited: Object.keys(fileActivity).length,
        topFiles,
        earliestActivity: extensionSessions[0]?.startTime || null,
        latestActivity: extensionSessions[extensionSessions.length - 1]?.endTime || null
      };

      console.log(`✅ Loaded ${extensionSessions.length} extension activity sessions`);
    } catch (error) {
      console.log(`⚠️ Could not load extension activity: ${error}`);
    }

    // 4. Load Git commit history
    let gitHistory: any = null;
    try {
      const gitResponse = await fetch(getApiUrl(`/api/projects/${projectId}/git-history`, request));
      if (gitResponse.ok) {
        gitHistory = await gitResponse.json();
        console.log(`✅ Loaded ${gitHistory.totalCommits} Git commits`);
      }
    } catch (error) {
      console.log(`⚠️ Could not load Git history: ${error}`);
    }

    // 4b. Load unified timeline (combines all data sources by day)
    let unifiedTimeline: any = null;
    try {
      const timelineResponse = await fetch(getApiUrl(`/api/projects/${projectId}/timeline`, request));
      if (timelineResponse.ok) {
        unifiedTimeline = await timelineResponse.json();
        console.log(`✅ Loaded unified timeline with ${unifiedTimeline.days.length} days`);
      }
    } catch (error) {
      console.log(`⚠️ Could not load unified timeline: ${error}`);
    }

    // 5. Analyze timeline
    const timeline = analyzeTimeline(allMessages);

    // 6. Calculate costs
    const costs = calculateCosts(allMessages);

    // 7. Extract features from codebase (static list for now)
    const features = getFeaturesList();

    // 8. Get tech stack
    const techStack = getTechStack();

    // 9. Generate report
    const report = {
      projectId,
      generatedAt: new Date().toISOString(),
      timeline,
      costs,
      features,
      techStack,
      extensionActivity,
      gitHistory,
      unifiedTimeline,
      summary: {
        totalConversations: conversations.length,
        totalMessages: allMessages.length,
        developmentPeriod: timeline.totalDays,
        estimatedCost: costs.costs.totalCost,
        extensionSessions: extensionActivity?.totalSessions || 0,
        filesEdited: extensionActivity?.uniqueFilesEdited || 0,
        gitCommits: gitHistory?.totalCommits || 0,
        linesAdded: gitHistory?.totalInsertions || 0,
        linesRemoved: gitHistory?.totalDeletions || 0,
        timelineDays: unifiedTimeline?.days.length || 0
      }
    };

    console.log(`✅ Audit report generated successfully`);

    return NextResponse.json(report);

  } catch (error) {
    console.error('Error generating audit report:', error);
    return NextResponse.json(
      { 
        error: 'Failed to generate audit report',
        details: error instanceof Error ? error.message : String(error)
      },
      { status: 500 }
    );
  }
}

// Helper: Analyze timeline from messages
function analyzeTimeline(messages: any[]): TimelineAnalysis {
  if (messages.length === 0) {
    return {
      firstActivity: null,
      lastActivity: null,
      totalDays: 0,
      activeDays: 0,
      totalSessions: 0,
      sessions: [],
      velocity: {
        messagesPerDay: 0,
        averageSessionLength: 0,
        peakProductivityHours: []
      }
    };
  }

  // Sort messages by time
  const sorted = [...messages].sort((a, b) => 
    new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
  );

  const firstActivity = new Date(sorted[0].createdAt);
  const lastActivity = new Date(sorted[sorted.length - 1].createdAt);
  const totalDays = Math.ceil((lastActivity.getTime() - firstActivity.getTime()) / (1000 * 60 * 60 * 24));

  // Group into sessions (gap > 4 hours = new session)
  const SESSION_GAP = 4 * 60 * 60 * 1000; // 4 hours
  const sessions: WorkSession[] = [];
  let currentSession: any = null;

  for (const msg of sorted) {
    const msgTime = new Date(msg.createdAt).getTime();

    if (!currentSession || msgTime - currentSession.endTime > SESSION_GAP) {
      // Start new session
      if (currentSession) {
        sessions.push(formatSession(currentSession));
      }
      
      currentSession = {
        messages: [msg],
        startTime: msgTime,
        endTime: msgTime,
        date: new Date(msgTime).toISOString().split('T')[0]
      };
    } else {
      // Add to current session
      currentSession.messages.push(msg);
      currentSession.endTime = msgTime;
    }
  }

  // Don't forget the last session
  if (currentSession) {
    sessions.push(formatSession(currentSession));
  }

  // Calculate velocity metrics
  const activeDays = new Set(sorted.map(m => 
    new Date(m.createdAt).toISOString().split('T')[0]
  )).size;

  const totalSessionMinutes = sessions.reduce((sum, s) => sum + s.duration, 0);
  const averageSessionLength = sessions.length > 0 ? totalSessionMinutes / sessions.length : 0;

  // Find peak productivity hours
  const hourCounts = new Map<number, number>();
  sorted.forEach(msg => {
    const hour = new Date(msg.createdAt).getHours();
    hourCounts.set(hour, (hourCounts.get(hour) || 0) + 1);
  });
  const peakProductivityHours = Array.from(hourCounts.entries())
    .sort((a, b) => b[1] - a[1])
    .slice(0, 3)
    .map(([hour]) => hour)
    .sort((a, b) => a - b);

  return {
    firstActivity,
    lastActivity,
    totalDays,
    activeDays,
    totalSessions: sessions.length,
    sessions,
    velocity: {
      messagesPerDay: messages.length / activeDays,
      averageSessionLength: Math.round(averageSessionLength),
      peakProductivityHours
    }
  };
}

function formatSession(sessionData: any): WorkSession {
  const duration = Math.ceil((sessionData.endTime - sessionData.startTime) / (1000 * 60));
  const userMessages = sessionData.messages.filter((m: any) => m.type === 1).length;
  const aiMessages = sessionData.messages.filter((m: any) => m.type === 2).length;

  // Extract topics (first 3 unique conversation names)
  const topics = [...new Set(sessionData.messages.map((m: any) => m.conversationName))].slice(0, 3);

  // Extract files
  const files = [...new Set(
    sessionData.messages.flatMap((m: any) => m.attachedFiles || [])
  )];

  return {
    sessionId: `session-${sessionData.date}-${sessionData.startTime}`,
    date: sessionData.date,
    startTime: new Date(sessionData.startTime),
    endTime: new Date(sessionData.endTime),
    duration,
    messageCount: sessionData.messages.length,
    userMessages,
    aiMessages,
    topics,
    filesWorkedOn: files
  };
}

// Helper: Calculate costs
function calculateCosts(messages: any[]): CostAnalysis {
  const userMessages = messages.filter(m => m.type === 1);
  const aiMessages = messages.filter(m => m.type === 2);

  // Calculate average message length
  const totalChars = messages.reduce((sum, m) => sum + (m.text?.length || 0), 0);
  const avgMessageLength = messages.length > 0 ? Math.round(totalChars / messages.length) : 0;

  // Estimate tokens (rough: 1 token ≈ 4 characters)
  const inputChars = userMessages.reduce((sum, m) => sum + (m.text?.length || 0), 0);
  const outputChars = aiMessages.reduce((sum, m) => sum + (m.text?.length || 0), 0);

  const inputTokens = Math.ceil(inputChars / 4);
  const outputTokens = Math.ceil(outputChars / 4);
  const totalTokens = inputTokens + outputTokens;

  // Claude Sonnet 3.5 pricing (Nov 2024)
  const INPUT_COST_PER_1M = 3.0;
  const OUTPUT_COST_PER_1M = 15.0;

  const inputCost = (inputTokens / 1_000_000) * INPUT_COST_PER_1M;
  const outputCost = (outputTokens / 1_000_000) * OUTPUT_COST_PER_1M;
  const totalAICost = inputCost + outputCost;

  return {
    messageStats: {
      totalMessages: messages.length,
      userMessages: userMessages.length,
      aiMessages: aiMessages.length,
      avgMessageLength
    },
    estimatedTokens: {
      input: inputTokens,
      output: outputTokens,
      total: totalTokens
    },
    costs: {
      inputCost: Math.round(inputCost * 100) / 100,
      outputCost: Math.round(outputCost * 100) / 100,
      totalCost: Math.round(totalAICost * 100) / 100,
      currency: 'USD'
    },
    model: 'Claude Sonnet 3.5',
    pricing: {
      inputPer1M: INPUT_COST_PER_1M,
      outputPer1M: OUTPUT_COST_PER_1M
    }
  };
}

// Helper: Get features list
function getFeaturesList(): Feature[] {
  return [
    {
      name: "Project Management",
      description: "Create, manage, and organize AI-coded projects",
      pages: ["/projects", "/project/[id]/overview", "/project/[id]/settings"],
      apis: ["/api/projects/create", "/api/projects/[id]", "/api/projects/delete"],
      status: "complete"
    },
    {
      name: "AI Chat Integration",
      description: "Real-time chat with AI assistants for development",
      pages: ["/project/[id]/v_ai_chat"],
      apis: ["/api/ai/chat", "/api/ai/conversation"],
      status: "complete"
    },
    {
      name: "Cursor Import",
      description: "Import historical conversations from Cursor IDE",
      pages: [],
      apis: ["/api/cursor/backfill", "/api/cursor/tag-sessions"],
      status: "complete"
    },
    {
      name: "GitHub Integration",
      description: "Connect GitHub repositories and browse code",
      pages: ["/connections"],
      apis: ["/api/github/connect", "/api/github/repos", "/api/github/repo-tree"],
      status: "complete"
    },
    {
      name: "Session Tracking",
      description: "Track development sessions and activity",
      pages: ["/project/[id]/sessions"],
      apis: ["/api/sessions/track", "/api/sessions/associate-project"],
      status: "complete"
    },
    {
      name: "Knowledge Base",
      description: "Document and organize project knowledge",
      pages: ["/project/[id]/context"],
      apis: ["/api/projects/[id]/knowledge/*"],
      status: "complete"
    },
    {
      name: "Planning & Automation",
      description: "Generate development plans and automate workflows",
      pages: ["/project/[id]/plan", "/project/[id]/automation"],
      apis: ["/api/projects/[id]/plan/mvp", "/api/projects/[id]/plan/marketing"],
      status: "in-progress"
    },
    {
      name: "Analytics & Costs",
      description: "Track development costs and project analytics",
      pages: ["/project/[id]/analytics", "/costs"],
      apis: ["/api/stats", "/api/projects/[id]/aggregate"],
      status: "in-progress"
    }
  ];
}

// Helper: Get tech stack
function getTechStack() {
  return {
    frontend: {
      framework: "Next.js 16.0.1",
      react: "19.2.0",
      typescript: "5.x",
      styling: "Tailwind CSS 4",
      uiComponents: "Radix UI + shadcn/ui",
      icons: "Lucide React",
      fonts: "Geist Sans, Geist Mono"
    },
    backend: {
      runtime: "Next.js API Routes",
      database: "Firebase Firestore",
      auth: "Firebase Auth",
      storage: "Firebase Storage"
    },
    integrations: [
      "Google Vertex AI",
      "Google Generative AI",
      "GitHub OAuth",
      "v0.dev SDK"
    ]
  };
}

