import { computed, type Ref } from 'vue'

import { centToYuan, formatMoney } from '@/shared/utils/money'
import type { Checkout, Order } from '../api/orders'

export interface CheckoutFormSnapshot {
  content: string
  coin_consumed_m: number
}

export interface CounterFormSnapshot {
  consumableAmountYuan: number
  coin_consumed_m: number
  otherAmountYuan: number
  depositDeductAmountYuan: number
  reason: string
  evidenceText: string
}

export interface CheckoutResource {
  key: string
  label: string
  price: string
  mode: string
  quantity: number
  unitPrice: number
}

export function useOrderCheckoutSnapshot(options: {
  order: Ref<Order | null>
  checkoutForm: Ref<CheckoutFormSnapshot>
  resourceUsage: Ref<Record<string, number>>
}) {
  const checkoutResources = computed(() => readSnapshotResources(options.order.value))
  const resourceChargeAmount = computed(() =>
    calculateResourceChargeAmount(checkoutResources.value, options.resourceUsage.value)
  )
  const snapshotHafCoinM = computed(() => getSnapshotHafCoinM(options.order.value))
  const remainingHafCoinM = computed(() =>
    roundQuantity(
      Math.max(snapshotHafCoinM.value - Number(options.checkoutForm.value.coin_consumed_m || 0), 0)
    )
  )

  function hydrateResourceUsage() {
    options.resourceUsage.value = normalizeResourceUsage(
      checkoutResources.value,
      options.resourceUsage.value
    )
  }

  function readResourceUsage(key: string) {
    return readResourceUsageAmount(options.resourceUsage.value, key)
  }

  function resourceLineAmount(item: CheckoutResource) {
    return roundMoney(readResourceUsage(item.key) * item.unitPrice)
  }

  function checkoutContentWithSummary() {
    return buildCheckoutContentWithSummary({
      content: options.checkoutForm.value.content,
      coinConsumedM: options.checkoutForm.value.coin_consumed_m,
      checkoutResources: checkoutResources.value,
      resourceUsage: options.resourceUsage.value,
      remainingHafCoinM: remainingHafCoinM.value,
    })
  }

  return {
    checkoutResources,
    resourceChargeAmount,
    snapshotHafCoinM,
    remainingHafCoinM,
    hydrateResourceUsage,
    readResourceUsage,
    isChargedResource,
    resourceLineAmount,
    checkoutContentWithSummary,
  }
}

export function readSnapshot(order: Order | null) {
  const snapshot = order?.account_snapshot
  return isRecord(snapshot) ? snapshot : null
}

export function readAssetSummary(order: Order | null) {
  const summary = readSnapshot(order)?.asset_summary
  return isRecord(summary) ? summary : null
}

export function readSnapshotResources(order: Order | null): CheckoutResource[] {
  const resources = readAssetSummary(order)?.resources
  if (!Array.isArray(resources)) return []
  return resources
    .filter(isRecord)
    .map(item => {
      const key = String(item.key || item.label || '')
      const label = String(item.label || key || '额外消耗品')
      const price = String(item.price || '')
      return {
        key,
        label,
        price,
        mode: String(item.mode || '收费'),
        quantity: readNumber(item.quantity),
        unitPrice: readUnitPrice(price),
      }
    })
    .filter(item => item.key && item.quantity > 0)
}

export function normalizeResourceUsage(
  resources: CheckoutResource[],
  current: Record<string, number>
) {
  const next: Record<string, number> = {}
  for (const item of resources) {
    next[item.key] = Math.min(Math.max(Number(current[item.key] || 0), 0), item.quantity)
  }
  return next
}

export function readResourceUsageAmount(resourceUsage: Record<string, number>, key: string) {
  return Math.max(Number(resourceUsage[key] || 0), 0)
}

export function isChargedResource(item: CheckoutResource) {
  return item.mode !== '赠送'
}

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

export function buildCheckoutContentWithSummary(options: {
  content: string
  coinConsumedM: number
  checkoutResources: CheckoutResource[]
  resourceUsage: Record<string, number>
  remainingHafCoinM: number
}) {
  const lines = [options.content.trim()].filter(Boolean)
  const usedResources = options.checkoutResources.filter(
    item => readResourceUsageAmount(options.resourceUsage, item.key) > 0
  )
  if (usedResources.length) {
    lines.push(
      `额外消耗品：${usedResources
        .map(item => {
          const used = readResourceUsageAmount(options.resourceUsage, item.key)
          const amount = roundMoney(used * item.unitPrice)
          return `${item.label} ${used}/${item.quantity}${
            isChargedResource(item) ? `，金额¥${money(amount)}` : '，赠送不扣款'
          }`
        })
        .join('；')}`
    )
  }
  if (Number(options.coinConsumedM || 0) > 0) {
    lines.push(
      `哈夫币消耗：${quantity(options.coinConsumedM)}M，预计剩余${quantity(
        options.remainingHafCoinM
      )}M`
    )
  }
  if (lines.length === 0) {
    lines.push('租客发起结账。')
  }
  return lines.join('\n')
}

export function hydrateCounterFormFromCheckout(checkout: Checkout): CounterFormSnapshot {
  return {
    consumableAmountYuan: amountYuan(checkout.consumable_amount_cent),
    coin_consumed_m: checkout.coin_consumed_m,
    otherAmountYuan: amountYuan(checkout.other_amount_cent),
    depositDeductAmountYuan: amountYuan(checkout.deposit_deduct_amount_cent),
    reason: '',
    evidenceText: '',
  }
}

export function calculateCounterTotal(counterForm: {
  consumableAmountYuan: number
  coin_consumed_m: number
  otherAmountYuan: number
  depositDeductAmountYuan: number
}) {
  return roundMoney(
    counterForm.consumableAmountYuan +
      counterForm.coin_consumed_m +
      counterForm.otherAmountYuan +
      counterForm.depositDeductAmountYuan
  )
}

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

export function orderEstimatedEndAt(order: Order | null) {
  const rentedAt = order?.rented_at
  const durationHours = Number(order?.estimated_duration_hours || 0)
  if (!rentedAt || durationHours <= 0) return undefined
  return new Date(new Date(rentedAt).getTime() + durationHours * 60 * 60 * 1000).toISOString()
}

export function orderRentAmount(item: Order, userID: number | undefined | null) {
  if (item.owner_id === userID) return amountYuan(item.owner_rent_amount_cent)
  if (item.renter_id === userID) return amountYuan(item.rent_amount_cent)
  return amountYuan(item.display_amount_cent)
}

export function ownerActualIncome(item: Order, userID: number | undefined | null) {
  if (item.owner_id !== userID) return null
  const value = item.checkout?.owner_income_amount_cent
  return typeof value === 'number' ? centToYuan(value) : null
}

export function formatHandoffRecordType(type: string) {
  const typeMap: Record<string, string> = {
    owner_handoff: '卖家交接',
    renter_checkout: '买家结账',
    owner_counter_checkout: '卖家反驳结账',
    renter_confirm_checkout: '买家确认结账',
    owner_accept_checkout: '卖家接受结账',
    admin_arbitration: '客服仲裁',
    dispute_opened: '发起申诉',
    checkout_dispute_opened: '发起结账争议',
    dispute_cancelled: '取消申诉',
    checkout_dispute_cancelled: '取消结账争议',
  }
  return typeMap[type] || type
}

export function linesToList(value: string) {
  return value
    .split('\n')
    .map(item => item.trim())
    .filter(Boolean)
}

export function money(value: unknown) {
  return formatMoney(readNumber(value))
}

export function amountYuan(cent: unknown) {
  if (cent !== undefined && cent !== null) return centToYuan(readNumber(cent))
  return 0
}

export function quantity(value: unknown) {
  const rounded = roundQuantity(readNumber(value))
  return Number.isInteger(rounded) ? `${rounded}` : rounded.toFixed(2)
}

export function readUnitPrice(priceText: string) {
  const normalized = priceText.replace(/，/g, ',').trim()
  const fractionMatch = normalized.match(/(\d+(?:\.\d+)?)\s*元\s*\/\s*(\d+(?:\.\d+)?)/)
  if (fractionMatch) {
    const amount = Number(fractionMatch[1])
    const count = Number(fractionMatch[2])
    return count > 0 ? roundMoney(amount / count) : 0
  }
  const singleMatch = normalized.match(/(\d+(?:\.\d+)?)\s*元/)
  if (singleMatch) return Number(singleMatch[1])
  const fallback = normalized.match(/(\d+(?:\.\d+)?)/)
  return fallback ? Number(fallback[1]) : 0
}

export function roundMoney(value: number) {
  return Math.round(Number(value || 0) * 10) / 10
}

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

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

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null
}
