/**
 * Pattern Detection Engine
 * Learns from order data to optimize operations
 */

import prisma from '@/lib/db';
import { PatternData, DEFAULT_THRESHOLDS } from './types';

interface OrderPatternInput {
  orderId: string;
  customerEmail: string;
  shippingAddress: Record<string, unknown>;
  subtotal: number;
  tax: number;
  shipping: number;
  total: number;
  paymentMethod?: string;
  items: Array<{
    productId: string;
    quantity: number;
    unitPrice: number;
  }>;
}

export async function recordOrderPatterns(order: OrderPatternInput): Promise<PatternData[]> {
  const patterns: PatternData[] = [];

  const state = (order.shippingAddress?.state as string)?.toUpperCase();
  if (state && order.subtotal > 0) {
    const taxRate = order.tax / order.subtotal;
    const taxPattern = await updatePattern(
      'tax_rate',
      `state:${state}`,
      { rate: taxRate, taxAmount: order.tax, subtotal: order.subtotal }
    );
    if (taxPattern) patterns.push(taxPattern);
  }

  return patterns;
}

async function updatePattern(
  patternType: string,
  patternKey: string,
  newValue: Record<string, unknown>
): Promise<PatternData | null> {
  const existing = await prisma.detectedPattern.findUnique({
    where: {
      patternType_patternKey: {
        patternType,
        patternKey,
      },
    },
  });

  if (existing) {
    const newSampleSize = existing.sampleSize + 1;
    const newConfidence = Math.min(0.99, 0.5 + (newSampleSize * 0.05));

    await prisma.detectedPattern.update({
      where: { id: existing.id },
      data: {
        detectedValue: JSON.parse(JSON.stringify(newValue)),
        sampleSize: newSampleSize,
        confidence: newConfidence,
        lastSeenAt: new Date(),
      },
    });

    return {
      patternType,
      patternKey,
      value: newValue,
      sampleSize: newSampleSize,
      confidence: newConfidence,
    };
  } else {
    await prisma.detectedPattern.create({
      data: {
        patternType,
        patternKey,
        detectedValue: JSON.parse(JSON.stringify(newValue)),
        sampleSize: 1,
        confidence: 0.5,
      },
    });

    return {
      patternType,
      patternKey,
      value: newValue,
      sampleSize: 1,
      confidence: 0.5,
    };
  }
}

export async function getActivePatterns(patternType?: string): Promise<PatternData[]> {
  const where: { isActive: boolean; patternType?: string; confidence?: { gte: number } } = {
    isActive: true,
    confidence: { gte: DEFAULT_THRESHOLDS.patternConfidenceThreshold },
  };
  
  if (patternType) {
    where.patternType = patternType;
  }

  const patterns = await prisma.detectedPattern.findMany({
    where,
    orderBy: { confidence: 'desc' },
  });

  return patterns.map((p: any) => ({
    patternType: p.patternType,
    patternKey: p.patternKey,
    value: p.detectedValue,
    sampleSize: p.sampleSize,
    confidence: p.confidence,
  }));
}

export async function checkForSignificantPatterns(): Promise<PatternData[]> {
  const significantPatterns = await prisma.detectedPattern.findMany({
    where: {
      isActive: true,
      appliedToSystem: false,
      confidence: { gte: DEFAULT_THRESHOLDS.patternConfidenceThreshold },
      sampleSize: { gte: 10 },
    },
    orderBy: { confidence: 'desc' },
    take: 10,
  });

  return significantPatterns.map((p: any) => ({
    patternType: p.patternType,
    patternKey: p.patternKey,
    value: p.detectedValue,
    sampleSize: p.sampleSize,
    confidence: p.confidence,
  }));
}
