import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';
import { prisma } from '@/lib/db';

export const dynamic = 'force-dynamic';

/**
 * GET /api/analytics/errors
 * Fetch error analytics data
 */
export async function GET(request: NextRequest) {
  try {
    const session = await getServerSession(authOptions);
    
    if (!session) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const searchParams = request.nextUrl.searchParams;
    const range = searchParams.get('range') || '7d';
    const severity = searchParams.get('severity') || 'all';

    // Calculate date range
    const now = new Date();
    let startDate = new Date();
    
    switch (range) {
      case '24h':
        startDate.setDate(now.getDate() - 1);
        break;
      case '7d':
        startDate.setDate(now.getDate() - 7);
        break;
      case '30d':
        startDate.setDate(now.getDate() - 30);
        break;
      case '90d':
        startDate.setDate(now.getDate() - 90);
        break;
      default:
        startDate.setDate(now.getDate() - 7);
    }

    // Fetch error logs from database
    const whereClause: any = {
      timestamp: {
        gte: startDate,
      },
    };

    if (severity !== 'all') {
      whereClause.severity = severity;
    }

    const errors = await prisma.errorLog.findMany({
      where: whereClause,
      orderBy: {
        timestamp: 'desc',
      },
      take: 100,
    });

    // Calculate stats
    const last24HoursDate = new Date();
    last24HoursDate.setDate(now.getDate() - 1);

    const stats = {
      totalErrors: errors.length,
      last24Hours: errors.filter((e: any) => e.timestamp >= last24HoursDate).length,
      last7Days: errors.filter((e: any) => e.timestamp >= new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000)).length,
      resolved: errors.filter((e: any) => e.status === 'resolved').length,
      unresolved: errors.filter((e: any) => e.status !== 'resolved').length,
      criticalErrors: errors.filter((e: any) => e.severity === 'critical').length,
    };

    // Generate trends
    const trends = generateTrends(errors, range);

    return NextResponse.json({
      success: true,
      stats,
      errors: errors.map((error: any) => ({
        id: error.id,
        type: error.type,
        message: error.message,
        timestamp: error.timestamp,
        severity: error.severity,
        status: error.status,
        count: error.count || 1,
        affectedUsers: error.affectedUsers || 0,
        browser: error.browser,
        os: error.os,
        stackTrace: error.stackTrace,
      })),
      trends,
    });
  } catch (error: any) {
    console.error('Error fetching analytics:', error);
    return NextResponse.json(
      { error: 'Failed to fetch error analytics', details: error.message },
      { status: 500 }
    );
  }
}

/**
 * POST /api/analytics/errors
 * Log a new error
 */
export async function POST(request: NextRequest) {
  try {
    const body = await request.json();
    const { type, message, severity = 'medium', stackTrace, browser, os, userId } = body;

    if (!type || !message) {
      return NextResponse.json(
        { error: 'Type and message are required' },
        { status: 400 }
      );
    }

    // Check if similar error exists (within last hour)
    const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000);
    const existingError = await prisma.errorLog.findFirst({
      where: {
        type,
        message,
        timestamp: {
          gte: oneHourAgo,
        },
      },
    });

    let errorLog;

    if (existingError) {
      // Update existing error count
      errorLog = await prisma.errorLog.update({
        where: { id: existingError.id },
        data: {
          count: (existingError.count || 1) + 1,
          affectedUsers: existingError.affectedUsers ? existingError.affectedUsers + 1 : 1,
          timestamp: new Date(), // Update to latest occurrence
        },
      });
    } else {
      // Create new error log
      errorLog = await prisma.errorLog.create({
        data: {
          type,
          message,
          severity,
          status: 'new',
          stackTrace,
          browser,
          os,
          userId,
          count: 1,
          affectedUsers: 1,
          timestamp: new Date(),
        },
      });
    }

    return NextResponse.json({
      success: true,
      errorLog,
    });
  } catch (error: any) {
    console.error('Error logging error:', error);
    return NextResponse.json(
      { error: 'Failed to log error', details: error.message },
      { status: 500 }
    );
  }
}

function generateTrends(errors: any[], range: string) {
  const trends: any[] = [];
  const now = new Date();
  let days = 7;

  switch (range) {
    case '24h':
      days = 1;
      break;
    case '7d':
      days = 7;
      break;
    case '30d':
      days = 30;
      break;
    case '90d':
      days = 90;
      break;
  }

  for (let i = days - 1; i >= 0; i--) {
    const date = new Date(now);
    date.setDate(date.getDate() - i);
    date.setHours(0, 0, 0, 0);

    const nextDate = new Date(date);
    nextDate.setDate(nextDate.getDate() + 1);

    const count = errors.filter(e => {
      const errorDate = new Date(e.timestamp);
      return errorDate >= date && errorDate < nextDate;
    }).length;

    trends.push({
      date: date.toISOString().split('T')[0],
      count,
    });
  }

  return trends;
}
