import type { Order } from '../api/orders'

export interface SnapshotResource {
  key: string
  label: string
  quantity: number
  unitPrice: number
  chargeMode: '赠送' | '收费'
}

export function readSnapshot(order: Order | null) {
  if (!order?.listing_snapshot) return null
  try {
    return JSON.parse(order.listing_snapshot) as Record<string, any>
  } catch {
    return null
  }
}

export function readNumber(value: unknown): number {
  const parsed = Number(value)
  return Number.isFinite(parsed) ? parsed : 0
}

export function roundQuantity(value: number): number {
  return Math.round(value * 10) / 10
}

export function roundMoney(value: number): number {
  return Math.round(value * 100) / 100
}

export function readSnapshotResources(order: Order | null): SnapshotResource[] {
  const snapshot = readSnapshot(order)
  if (!snapshot?.quantities) return []

  const quantities = snapshot.quantities as Record<string, any>[]
  return quantities
    .map((item) => ({
      key: String(item.key || ''),
      label: String(item.label || ''),
      quantity: readNumber(item.quantity),
      unitPrice: readNumber(item.price),
      chargeMode: (item.charge_mode === '收费' ? '收费' : '赠送') as SnapshotResource['chargeMode'],
    }))
    .filter((item) => item.key && item.label)
}

export function isChargedResource(resource: SnapshotResource): boolean {
  return resource.chargeMode === '收费'
}

export function getSnapshotHafCoinM(order: Order | null): number {
  const snapshot = readSnapshot(order)
  return roundQuantity(readNumber(snapshot?.haf_coin_amount) / 1000000)
}

export function calculateResourceChargeAmount(
  resources: SnapshotResource[],
  resourceUsage: Record<string, number>
): number {
  return roundMoney(
    resources.reduce((sum, item) => {
      if (!isChargedResource(item)) return sum
      const used = resourceUsage[item.key] || 0
      return sum + used * item.unitPrice
    }, 0)
  )
}

export function calculateCheckoutTotal(
  resourceCharge: number,
  consumableAmount: number,
  coinConsumed: number,
  otherAmount: number
): number {
  return roundMoney(resourceCharge + consumableAmount + coinConsumed + otherAmount)
}

export function calculateCounterTotal(counterForm: {
  consumable_amount: number
  coin_consumed_m: number
  other_amount: number
  deposit_deduct_amount: number
}): number {
  return roundMoney(
    counterForm.consumable_amount +
      counterForm.coin_consumed_m +
      counterForm.other_amount +
      counterForm.deposit_deduct_amount
  )
}

export function hydrateResourceUsageFromOrder(
  order: Order | null,
  resources: SnapshotResource[]
): Record<string, number> {
  const usage: Record<string, number> = {}

  if (!order?.checkout_info) {
    return usage
  }

  try {
    const info = JSON.parse(order.checkout_info) as Record<string, any>
    const consumedResources = info.consumed_resources as Record<string, number> | undefined

    if (consumedResources) {
      resources.forEach((res) => {
        if (res.key in consumedResources) {
          usage[res.key] = consumedResources[res.key] ?? 0
        }
      })
    }
  } catch {
    // ignore
  }

  return usage
}

export function hydrateCounterFormFromOrder(order: Order | null) {
  if (!order?.counter_info) {
    return null
  }

  try {
    const info = JSON.parse(order.counter_info) as Record<string, any>
    return {
      consumable_amount: readNumber(info.consumable_amount),
      coin_consumed_m: readNumber(info.coin_consumed_m),
      other_amount: readNumber(info.other_amount),
      deposit_deduct_amount: readNumber(info.deposit_deduct_amount),
      reason: String(info.reason || ''),
      evidenceText: String(info.evidence || ''),
    }
  } catch {
    return null
  }
}

export function readError(error: unknown, fallback: string): string {
  if (error && typeof error === 'object' && 'message' in error) {
    return String(error.message)
  }
  return fallback
}
