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

// GET /api/payment-latency - Get payment latency data
export async function GET(req: NextRequest) {
  try {
    const session = await getServerSession();
    if (!session?.user?.email) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const { searchParams } = new URL(req.url);
    const contractId = searchParams.get('contractId');

    const where: any = {};
    if (contractId) {
      where.contractId = contractId;
    }

    const latencies = await prisma.paymentLatency.findMany({
      where,
      orderBy: { createdAt: 'desc' },
      take: 50,
    });

    // Calculate average latencies
    const avgLatencies = {
      quoteToAcceptance: 0,
      acceptanceToContract: 0,
      contractToWorkStart: 0,
      workStartToCompletion: 0,
      completionToInvoice: 0,
      invoiceToPayment: 0,
      totalLatency: 0,
    };

    if (latencies.length > 0) {
      const validLatencies = latencies.filter((l: any) => l.totalLatency);
      if (validLatencies.length > 0) {
        avgLatencies.quoteToAcceptance =
          validLatencies.reduce((sum: number, l: any) => sum + (l.quoteToAcceptance || 0), 0) / validLatencies.length;
        avgLatencies.acceptanceToContract =
          validLatencies.reduce((sum: number, l: any) => sum + (l.acceptanceToContract || 0), 0) / validLatencies.length;
        avgLatencies.contractToWorkStart =
          validLatencies.reduce((sum: number, l: any) => sum + (l.contractToWorkStart || 0), 0) / validLatencies.length;
        avgLatencies.workStartToCompletion =
          validLatencies.reduce((sum: number, l: any) => sum + (l.workStartToCompletion || 0), 0) / validLatencies.length;
        avgLatencies.completionToInvoice =
          validLatencies.reduce((sum: number, l: any) => sum + (l.completionToInvoice || 0), 0) / validLatencies.length;
        avgLatencies.invoiceToPayment =
          validLatencies.reduce((sum: number, l: any) => sum + (l.invoiceToPayment || 0), 0) / validLatencies.length;
        avgLatencies.totalLatency =
          validLatencies.reduce((sum: number, l: any) => sum + (l.totalLatency || 0), 0) / validLatencies.length;
      }
    }

    return NextResponse.json({ latencies, avgLatencies });
  } catch (error) {
    console.error('Error fetching payment latency:', error);
    return NextResponse.json(
      { error: 'Failed to fetch payment latency' },
      { status: 500 }
    );
  }
}

// POST /api/payment-latency - Track payment latency
export async function POST(req: NextRequest) {
  try {
    const session = await getServerSession();
    if (!session?.user?.email) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const body = await req.json();
    const { contractId, stage, timestamp } = body;

    if (!contractId || !stage) {
      return NextResponse.json(
        { error: 'Contract ID and stage are required' },
        { status: 400 }
      );
    }

    // Get existing latency record or create new one
    let latency = await prisma.paymentLatency.findUnique({
      where: { contractId },
    });

    const updateData: any = {};
    const now = timestamp ? new Date(timestamp) : new Date();

    // Update the appropriate timestamp based on stage
    switch (stage) {
      case 'quote_created':
        updateData.quoteCreatedAt = now;
        break;
      case 'quote_sent':
        updateData.quoteSentAt = now;
        break;
      case 'quote_accepted':
        updateData.quoteAcceptedAt = now;
        break;
      case 'contract_signed':
        updateData.contractSignedAt = now;
        break;
      case 'work_started':
        updateData.workStartedAt = now;
        break;
      case 'work_completed':
        updateData.workCompletedAt = now;
        break;
      case 'invoice_sent':
        updateData.invoiceSentAt = now;
        break;
      case 'payment_received':
        updateData.paymentReceivedAt = now;
        break;
    }

    if (latency) {
      // Update existing record
      latency = await prisma.paymentLatency.update({
        where: { contractId },
        data: updateData,
      });
    } else {
      // Create new record
      latency = await prisma.paymentLatency.create({
        data: {
          contractId,
          quoteCreatedAt: now,
          ...updateData,
        },
      });
    }

    // Calculate latencies if we have the necessary timestamps
    if (latency.quoteCreatedAt) {
      const calculations: any = {};

      if (latency.quoteAcceptedAt) {
        calculations.quoteToAcceptance =
          (latency.quoteAcceptedAt.getTime() - latency.quoteCreatedAt.getTime()) / (1000 * 60 * 60);
      }

      if (latency.quoteAcceptedAt && latency.contractSignedAt) {
        calculations.acceptanceToContract =
          (latency.contractSignedAt.getTime() - latency.quoteAcceptedAt.getTime()) / (1000 * 60 * 60);
      }

      if (latency.contractSignedAt && latency.workStartedAt) {
        calculations.contractToWorkStart =
          (latency.workStartedAt.getTime() - latency.contractSignedAt.getTime()) / (1000 * 60 * 60);
      }

      if (latency.workStartedAt && latency.workCompletedAt) {
        calculations.workStartToCompletion =
          (latency.workCompletedAt.getTime() - latency.workStartedAt.getTime()) / (1000 * 60 * 60);
      }

      if (latency.workCompletedAt && latency.invoiceSentAt) {
        calculations.completionToInvoice =
          (latency.invoiceSentAt.getTime() - latency.workCompletedAt.getTime()) / (1000 * 60 * 60);
      }

      if (latency.invoiceSentAt && latency.paymentReceivedAt) {
        calculations.invoiceToPayment =
          (latency.paymentReceivedAt.getTime() - latency.invoiceSentAt.getTime()) / (1000 * 60 * 60);
      }

      if (latency.paymentReceivedAt) {
        calculations.totalLatency =
          (latency.paymentReceivedAt.getTime() - latency.quoteCreatedAt.getTime()) / (1000 * 60 * 60);
      }

      // Update with calculations
      if (Object.keys(calculations).length > 0) {
        latency = await prisma.paymentLatency.update({
          where: { contractId },
          data: calculations,
        });
      }
    }

    return NextResponse.json({ latency, message: 'Latency tracked successfully' });
  } catch (error) {
    console.error('Error tracking payment latency:', error);
    return NextResponse.json(
      { error: 'Failed to track payment latency' },
      { status: 500 }
    );
  }
}
