import { NextRequest, NextResponse } from 'next/server';
import { getPrisma } from '@/lib/db';
import crypto from 'crypto';

function safeCompare(a: string, b: string): boolean {
  const bufA = Buffer.from(a);
  const bufB = Buffer.from(b);
  if (bufA.length !== bufB.length) {
    crypto.timingSafeEqual(bufA, bufA);
    return false;
  }
  return crypto.timingSafeEqual(bufA, bufB);
}

export async function POST(req: NextRequest) {
  try {
    const signature = req.headers.get('x-n8n-signature') || '';
    const expectedSecret = process.env.N8N_WEBHOOK_SECRET || '';

    if (!expectedSecret || !signature || !safeCompare(signature, expectedSecret)) {
      return NextResponse.json({
        success: false,
        error: {
          code: 'UNAUTHORIZED',
          metadata: { message: 'Invalid or missing signature.' }
        }
      }, { status: 401 });
    }

    const body = await req.json();
    const { sales } = body;

    if (!Array.isArray(sales)) {
      return NextResponse.json({
        success: false,
        error: {
          code: 'BAD_REQUEST',
          metadata: { message: 'sales must be an array.' }
        }
      }, { status: 400 });
    }

    const prisma = getPrisma();

    // Query all unique collaborator usernames and hotel codes to validate them
    const uniqueUsernames = Array.from(new Set(sales.map(s => s.username).filter(Boolean))) as string[];
    const uniqueHotelCodes = Array.from(new Set(sales.map(s => s.hotelCode).filter(Boolean))) as string[];

    const validationResults = await prisma.$transaction(async (tx: any) => {
      await tx.$executeRawUnsafe(`SET LOCAL app.current_user_role = 'admin';`);

      const dbUsers = await tx.user.findMany({
        where: { username: { in: uniqueUsernames } }
      });
      const dbHotels = await tx.hotel.findMany({
        where: { code: { in: uniqueHotelCodes } }
      });

      const userMap = new Map<string, any>(dbUsers.map((u: any) => [u.username, u]));
      const hotelMap = new Map<string, any>(dbHotels.map((h: any) => [h.code, h]));

      const results = [];

      for (const s of sales) {
        const user = userMap.get(s.username);
        const hotel = hotelMap.get(s.hotelCode);

        if (!user) {
          results.push({
            ...s,
            isValid: false,
            invalidReason: 'COLLABORATOR_NOT_FOUND',
            avgAmount: 0,
            stdDev: 0,
            threshold: 0,
            historicalCount: 0
          });
          continue;
        }

        if (!hotel) {
          results.push({
            ...s,
            isValid: false,
            invalidReason: 'HOTEL_NOT_FOUND',
            avgAmount: 0,
            stdDev: 0,
            threshold: 0,
            historicalCount: 0
          });
          continue;
        }

        // Fetch historical sales results for this user to compute standard deviation
        const historicalSales = await tx.salesResult.findMany({
          where: { userId: user.id },
          select: { amount: true }
        });

        const amounts = historicalSales.map((h: any) => Number(h.amount));
        const count = amounts.length;
        
        const avgAmount = count > 0 ? amounts.reduce((a: number, b: number) => a + b, 0) / count : Number(s.amount);
        const variance = count > 1 ? amounts.reduce((a: number, b: number) => a + Math.pow(b - avgAmount, 2), 0) / (count - 1) : 0;
        const stdDev = count > 1 ? Math.sqrt(variance) : 0;
        const threshold = avgAmount + 2.5 * stdDev;

        results.push({
          ...s,
          isValid: true,
          avgAmount,
          stdDev,
          threshold,
          historicalCount: count
        });
      }
      return results;
    });


    return NextResponse.json({
      success: true,
      validationResults
    }, { status: 200 });

  } catch (err: any) {
    console.error('validate-sales error:', err);
    return NextResponse.json({
      success: false,
      error: {
        code: 'VALIDATE_SALES_FAILED',
        metadata: { message: err.message }
      }
    }, { status: 500 });
  }
}
