interface QuoteSnapshot {
  version: number
  validUntil: string | null
  subtotal: number
  markup: number
  markupPercent: number
  taxAmount: number
  taxPercent: number
  totalAmount: number
  currency: string
  notes: string | null
  termsConditions: string | null
  items: {
    serviceType: string
    description: string
    dayNumber: number | null
    quantity: number
    unitCost: number
    totalCost: number
    sortOrder: number
  }[]
}

export function buildQuoteSnapshot(quote: any, items: any[]): QuoteSnapshot {
  return {
    version: quote.version,
    validUntil: quote.validUntil ? new Date(quote.validUntil).toISOString() : null,
    subtotal: Number(quote.subtotal),
    markup: Number(quote.markup),
    markupPercent: Number(quote.markupPercent),
    taxAmount: Number(quote.taxAmount),
    taxPercent: Number(quote.taxPercent),
    totalAmount: Number(quote.totalAmount),
    currency: quote.currency,
    notes: quote.notes || null,
    termsConditions: quote.termsConditions || null,
    items: items.map((item: any) => ({
      serviceType: item.serviceType,
      description: item.description,
      dayNumber: item.dayNumber ?? null,
      quantity: Number(item.quantity),
      unitCost: Number(item.unitCost),
      totalCost: Number(item.totalCost),
      sortOrder: Number(item.sortOrder),
    })),
  }
}

export function computeChangeSummary(
  oldSnapshot: QuoteSnapshot,
  newItems: any[],
  newFields: any
): string {
  const changes: string[] = []

  // Quote-level field changes
  if (newFields.markupPercent !== undefined) {
    const newMarkup = parseFloat(newFields.markupPercent) || 0
    if (newMarkup !== oldSnapshot.markupPercent) {
      changes.push(`Changed markup from ${oldSnapshot.markupPercent}% to ${newMarkup}%`)
    }
  }

  if (newFields.taxPercent !== undefined) {
    const newTax = parseFloat(newFields.taxPercent) || 0
    if (newTax !== oldSnapshot.taxPercent) {
      changes.push(`Changed tax from ${oldSnapshot.taxPercent}% to ${newTax}%`)
    }
  }

  if (newFields.currency !== undefined && newFields.currency !== oldSnapshot.currency) {
    changes.push(`Changed currency from ${oldSnapshot.currency} to ${newFields.currency}`)
  }

  if (newFields.notes !== undefined) {
    const newNotes = newFields.notes || null
    if (newNotes !== oldSnapshot.notes) {
      changes.push('Updated notes')
    }
  }

  if (newFields.termsConditions !== undefined) {
    const newTerms = newFields.termsConditions || null
    if (newTerms !== oldSnapshot.termsConditions) {
      changes.push('Updated terms & conditions')
    }
  }

  // Item-level changes
  const oldItemMap = new Map<string, typeof oldSnapshot.items[number]>()
  for (const item of oldSnapshot.items) {
    const key = `${item.serviceType}::${item.description}`
    oldItemMap.set(key, item)
  }

  const newItemMap = new Map<string, any>()
  for (const item of newItems) {
    const key = `${item.serviceType}::${item.description || ''}`
    newItemMap.set(key, item)
  }

  // Detect added items
  for (const [key] of newItemMap) {
    if (!oldItemMap.has(key)) {
      const item = newItemMap.get(key)
      changes.push(`Added '${item.description || item.serviceType}' (${item.serviceType})`)
    }
  }

  // Detect removed items
  for (const [key] of oldItemMap) {
    if (!newItemMap.has(key)) {
      const item = oldItemMap.get(key)!
      changes.push(`Removed '${item.description || item.serviceType}' (${item.serviceType})`)
    }
  }

  // Detect modified items
  for (const [key] of newItemMap) {
    if (oldItemMap.has(key)) {
      const oldItem = oldItemMap.get(key)!
      const newItem = newItemMap.get(key)
      const mods: string[] = []

      const newQty = parseInt(newItem.quantity) || 1
      if (newQty !== oldItem.quantity) {
        mods.push(`qty ${oldItem.quantity} \u2192 ${newQty}`)
      }

      const newUnitCost = parseFloat(newItem.unitCost) || 0
      if (newUnitCost !== oldItem.unitCost) {
        mods.push(`unitCost ${oldItem.unitCost} \u2192 ${newUnitCost}`)
      }

      if (mods.length > 0) {
        changes.push(`Modified '${oldItem.description || oldItem.serviceType}': ${mods.join(', ')}`)
      }
    }
  }

  return changes.length > 0 ? changes.join('. ') + '.' : 'No significant changes detected.'
}
