import { WORK_ORDER_STATUS } from '../../domain/work-order-status.js'
import {
  createWorkOrderEvent,
  deductPendingDepositUnfreeze,
} from '../../repositories/worker-platform/index.js'
import type { JsonObject } from '../../types/json.js'
import { createHttpError } from '../../utils/http.js'
import { nowIso } from '../../utils/time.js'
import { publishWorkOrderRealtimeChange } from '../realtime/realtime-event-service.js'
import { normalizeAmountFen } from './mappers.js'
import { resolveWorkOrderRealtimeWorkerIds } from './admin-work-order-realtime-service.js'
import { getRequiredWorkOrder } from './worker-session-context-service.js'

export async function deductAdminWorkOrderPendingDeposit(
  workOrderId: number | string,
  payload: JsonObject = {},
  actorName = '',
) {
  const workOrder = await getRequiredWorkOrder(workOrderId)
  if (workOrder.status !== WORK_ORDER_STATUS.ACCEPTED) {
    throw createHttpError('只有已验收的工单可以扣减待解冻押金', {
      statusCode: 409,
      errorCode: 'work_order_deduct_pending_status_invalid',
    })
  }
  const amount = normalizeAmountFen(payload.amount ?? payload.amountYuan, 0)
  const note = String(payload.note || payload.reason || '').trim()
  if (amount <= 0) {
    throw createHttpError('扣减金额必须大于 0', {
      statusCode: 400,
      errorCode: 'work_order_deduct_pending_amount_invalid',
    })
  }
  if (!note) {
    throw createHttpError('请填写扣减原因', {
      statusCode: 400,
      errorCode: 'work_order_deduct_pending_note_required',
    })
  }
  const result = await deductPendingDepositUnfreeze({
    workOrderId: workOrder.id,
    amount,
    note,
    now: nowIso(),
  })
  if (result.failureReason === 'no_pending_deposit') {
    throw createHttpError('该工单没有待解冻的押金', {
      statusCode: 409,
      errorCode: 'work_order_deduct_pending_none',
    })
  }
  if (result.failureReason === 'amount_exceeds_pending') {
    throw createHttpError('扣减金额超过该工单待解冻押金总额', {
      statusCode: 409,
      errorCode: 'work_order_deduct_pending_amount_exceeds',
    })
  }
  await createWorkOrderEvent({
    workOrderId: workOrder.id,
    actorType: 'admin',
    actorId: actorName,
    eventType: 'pending_deposit_deducted',
    fromStatus: workOrder.status,
    toStatus: workOrder.status,
    payloadJson: JSON.stringify({ amount, note }),
    now: nowIso(),
  })
  publishWorkOrderRealtimeChange({
    workOrderId: Number(workOrder.id),
    workerIds: await resolveWorkOrderRealtimeWorkerIds(workOrder),
  })
  return { deductedAmount: result.deductedAmount }
}
