import { NextRequest, NextResponse } from 'next/server';
import { exec } from 'child_process';
import { promisify } from 'util';

const execAsync = promisify(exec);

interface GitCommit {
  hash: string;
  date: string;
  author: string;
  message: string;
  filesChanged: number;
  insertions: number;
  deletions: number;
}

interface GitStats {
  totalCommits: number;
  firstCommit: string | null;
  lastCommit: string | null;
  totalFilesChanged: number;
  totalInsertions: number;
  totalDeletions: number;
  commits: GitCommit[];
  topFiles: Array<{ filePath: string; changeCount: number }>;
  commitsByDay: Record<string, number>;
  authors: Array<{ name: string; commitCount: number }>;
}

export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ projectId: string }> }
) {
  try {
    const { projectId } = await params;
    
    // For now, we'll use the current workspace
    // In the future, we can store git repo path in project metadata
    const repoPath = '/Users/markhenderson/ai-proxy';

    // Get all commits with detailed stats
    const { stdout: commitsOutput } = await execAsync(
      `cd "${repoPath}" && git log --all --pretty=format:"%H|%ai|%an|%s" --numstat`,
      { maxBuffer: 10 * 1024 * 1024 } // 10MB buffer for large repos
    );

    if (!commitsOutput.trim()) {
      return NextResponse.json({
        totalCommits: 0,
        firstCommit: null,
        lastCommit: null,
        totalFilesChanged: 0,
        totalInsertions: 0,
        totalDeletions: 0,
        commits: [],
        topFiles: [],
        commitsByDay: {},
        authors: []
      });
    }

    // Parse commit data
    const commits: GitCommit[] = [];
    const fileChangeCounts = new Map<string, number>();
    const commitsByDay: Record<string, number> = {};
    const authorCounts = new Map<string, number>();
    
    let totalFilesChanged = 0;
    let totalInsertions = 0;
    let totalDeletions = 0;

    const lines = commitsOutput.split('\n');
    let currentCommit: Partial<GitCommit> | null = null;

    for (const line of lines) {
      if (line.includes('|')) {
        // This is a commit header line
        if (currentCommit) {
          commits.push(currentCommit as GitCommit);
        }

        const [hash, date, author, message] = line.split('|');
        currentCommit = {
          hash: hash.substring(0, 8),
          date,
          author,
          message,
          filesChanged: 0,
          insertions: 0,
          deletions: 0
        };

        // Count commits by day
        const day = date.split(' ')[0];
        commitsByDay[day] = (commitsByDay[day] || 0) + 1;

        // Count commits by author
        authorCounts.set(author, (authorCounts.get(author) || 0) + 1);

      } else if (line.trim() && currentCommit) {
        // This is a file stat line (insertions, deletions, filename)
        const parts = line.trim().split('\t');
        if (parts.length === 3) {
          const [insertStr, delStr, filepath] = parts;
          const insertions = insertStr === '-' ? 0 : parseInt(insertStr, 10) || 0;
          const deletions = delStr === '-' ? 0 : parseInt(delStr, 10) || 0;

          currentCommit.filesChanged!++;
          currentCommit.insertions! += insertions;
          currentCommit.deletions! += deletions;

          totalFilesChanged++;
          totalInsertions += insertions;
          totalDeletions += deletions;

          fileChangeCounts.set(filepath, (fileChangeCounts.get(filepath) || 0) + 1);
        }
      }
    }

    // Push the last commit
    if (currentCommit) {
      commits.push(currentCommit as GitCommit);
    }

    // Sort commits by date (most recent first)
    commits.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());

    const firstCommit = commits.length > 0 ? commits[commits.length - 1].date : null;
    const lastCommit = commits.length > 0 ? commits[0].date : null;

    // Get top 20 most changed files
    const topFiles = Array.from(fileChangeCounts.entries())
      .sort(([, countA], [, countB]) => countB - countA)
      .slice(0, 20)
      .map(([filePath, changeCount]) => ({ filePath, changeCount }));

    // Get author stats
    const authors = Array.from(authorCounts.entries())
      .sort(([, countA], [, countB]) => countB - countA)
      .map(([name, commitCount]) => ({ name, commitCount }));

    const stats: GitStats = {
      totalCommits: commits.length,
      firstCommit,
      lastCommit,
      totalFilesChanged,
      totalInsertions,
      totalDeletions,
      commits: commits.slice(0, 50), // Return last 50 commits for display
      topFiles,
      commitsByDay,
      authors
    };

    return NextResponse.json(stats);

  } catch (error) {
    console.error('Error loading Git history:', error);
    return NextResponse.json(
      { 
        error: 'Could not load Git history', 
        details: error instanceof Error ? error.message : String(error) 
      },
      { status: 500 }
    );
  }
}

