import { WORK_ORDER_STATUS } from '../../domain/work-order-status.js'
import { createWorkOrderEvent, updateWorkOrder } 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 { safeParseJson } from '../admin/admin-query-utils.js'
import { resolveAdminNotificationEntity } from '../admin/admin-notification-service.js'
import { publishWorkOrderRealtimeChange } from '../realtime/realtime-event-service.js'
import {
  mapWorkOrderAdmin,
  normalizeAmountFen,
  normalizeSubmittedFields,
  normalizeUploadedFiles,
  resolveRequirementFields,
} from './mappers.js'
import { resolveWorkOrderRealtimeWorkerIds } from './admin-work-order-realtime-service.js'
import { getRequiredWorkOrder } from './worker-session-context-service.js'

export async function submitAdminWorkOrderMaterial(
  workOrderId: number | string,
  payload: JsonObject = {},
  actorName = '',
) {
  const workOrder = await getRequiredWorkOrder(workOrderId)
  const materialCapabilities = mapWorkOrderAdmin(workOrder).capabilities
  if (!materialCapabilities.canUpdateMaterial) {
    throw createHttpError('当前状态不能更新订单资料', {
      statusCode: 409,
      errorCode: 'work_order_material_status_invalid',
    })
  }

  const fields = resolveRequirementFields(workOrder)
  const submittedFields = normalizeSubmittedFields(payload.fields || payload.material || payload)
  const complete = fields.every(
    (field) => !field.required || String(submittedFields[field.key] || '').trim(),
  )
  const now = nowIso()
  const screenshots = normalizeUploadedFiles(payload.screenshots || payload.files)
  const hasActiveShares = Number(workOrder.active_share_quantity || 0) > 0
  const rewardAmount = resolveAdminMaterialRewardAmount({
    currentRewardAmount: Number(workOrder.reward_amount || 0),
    requestedRewardAmount: payload.rewardAmount,
    sharingEnabled: workOrder.sharing_enabled === true,
    activeShareQuantity: Number(workOrder.active_share_quantity || 0),
  })
  const material = {
    ...safeParseJson(workOrder.material_json),
    collect: {
      fields: submittedFields,
      screenshots,
      submittedAt: now,
      complete,
      source: 'admin',
    },
  }
  const nextStatus =
    hasActiveShares ||
    workOrder.status === WORK_ORDER_STATUS.OPEN ||
    workOrder.status === WORK_ORDER_STATUS.IN_PROGRESS
      ? workOrder.status
      : complete
        ? WORK_ORDER_STATUS.UNASSIGNED
        : WORK_ORDER_STATUS.PENDING_MATERIAL
  const updated = await updateWorkOrder(workOrder.id, {
    status: nextStatus,
    material_json: material,
    reward_amount: rewardAmount,
    updated_at: now,
  })
  await createWorkOrderEvent({
    workOrderId: workOrder.id,
    actorType: 'admin',
    actorId: actorName,
    eventType:
      hasActiveShares ||
      workOrder.status === WORK_ORDER_STATUS.OPEN ||
      workOrder.status === WORK_ORDER_STATUS.IN_PROGRESS
        ? 'material_updated'
        : 'material_completed',
    fromStatus: workOrder.status,
    toStatus: nextStatus,
    payloadJson: JSON.stringify({
      fields: submittedFields,
      complete,
      previousRewardAmount: Number(workOrder.reward_amount || 0),
      rewardAmount,
    }),
    now,
  })
  if (nextStatus !== WORK_ORDER_STATUS.PENDING_MATERIAL) {
    await resolveAdminNotificationEntity('work_order', Number(workOrder.id), 'material_completed')
  }
  publishWorkOrderRealtimeChange({
    workOrderId: Number(workOrder.id),
    workerIds: await resolveWorkOrderRealtimeWorkerIds(workOrder),
  })
  return { order: mapWorkOrderAdmin(updated || workOrder), complete }
}

/** 更新资料时仅普通接单可改价；已有参与者的拼单必须保留份额价格快照。 */
export function resolveAdminMaterialRewardAmount(input: {
  currentRewardAmount: number
  requestedRewardAmount: unknown
  sharingEnabled: boolean
  activeShareQuantity: number
}): number {
  if (input.requestedRewardAmount === undefined) return input.currentRewardAmount
  if (input.sharingEnabled && input.activeShareQuantity > 0) {
    throw createHttpError('拼单订单的份额奖励已锁定，不能在更新资料时修改价格', {
      statusCode: 409,
      errorCode: 'work_order_material_reward_sharing_invalid',
    })
  }
  return normalizeAmountFen(input.requestedRewardAmount, input.currentRewardAmount)
}
