import { ServiceBill } from '@/lib/types'

/**
 * Calculates the predicted amount for the next month based on historical data.
 * Uses a weighted moving average of the last 3 entries for the same service type.
 * Weights: 50% (most recent), 30% (previous), 20% (oldest).
 */
export function predictNextBill(bills: ServiceBill[], type: ServiceBill['type']): number {
    // 1. Filter bills by type
    const relevantBills = bills
        .filter((b) => b.type === type)
        .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()) // Newest first

    if (relevantBills.length === 0) return 0

    // 2. Take up to 3 most recent bills
    const recent = relevantBills.slice(0, 3)

    // 3. Calculate weighted average
    let totalWeight = 0
    let weightedSum = 0

    // Weights for 1, 2, or 3 months
    const weights = [0.5, 0.3, 0.2]

    recent.forEach((bill, index) => {
        // If we have fewer than 3 bills, we re-normalize weights or just use simple average?
        // Let's stick to the weights but normalize if unmatched.
        // Actually, simple approach:
        // 1 bill: 100%
        // 2 bills: 62.5% / 37.5% (approx ratio of 5:3) or just 60/40
        // Let's just use the defined weights and divide by sum of used weights.

        const w = weights[index]
        weightedSum += bill.amount * w
        totalWeight += w
    })

    return weightedSum / totalWeight
}

/**
 * Calculates the percentage trend compared to the average of previous bills.
 * Positive = Spending more. Negative = Spending less.
 */
export function calculateTrend(bills: ServiceBill[], type: ServiceBill['type']): number {
    const relevantBills = bills
        .filter((b) => b.type === type)
        .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())

    if (relevantBills.length < 2) return 0

    const latest = relevantBills[0].amount
    const previous = relevantBills.slice(1, 4) // Average of up to 3 previous bills

    if (previous.length === 0) return 0

    const avgPrevious = previous.reduce((sum, b) => sum + b.amount, 0) / previous.length

    return ((latest - avgPrevious) / avgPrevious) * 100
}
