import {
  revokeAllWorkerSessions,
  updateWorkerPassword,
} 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 {
  hashWorkerPassword,
  mapWorkerUser,
  normalizePassword,
  normalizeSessionVersion,
  validateWorkerPassword,
  verifyWorkerPassword,
} from './mappers.js'
import { getRequiredWorker, type WorkerSession } from './worker-session-context-service.js'

export async function changeWorkerPassword(payload: JsonObject = {}, session: WorkerSession) {
  const worker = await getRequiredWorker(session.workerId)
  const currentPassword = normalizePassword(payload.currentPassword || payload.oldPassword)
  const nextPassword = normalizePassword(payload.newPassword || payload.password)

  if (!currentPassword) {
    throw createHttpError('请输入当前密码', {
      statusCode: 400,
      errorCode: 'worker_password_current_required',
    })
  }

  if (!verifyWorkerPassword(currentPassword, worker.password_hash)) {
    throw createHttpError('当前密码不正确', {
      statusCode: 400,
      errorCode: 'worker_password_current_invalid',
    })
  }

  if (!nextPassword) {
    throw createHttpError('请输入新密码', {
      statusCode: 400,
      errorCode: 'worker_password_new_required',
    })
  }

  validateWorkerPassword(nextPassword)
  if (currentPassword === nextPassword) {
    throw createHttpError('新密码不能与当前密码一致', {
      statusCode: 400,
      errorCode: 'worker_password_unchanged',
    })
  }

  const now = nowIso()
  const updated = await updateWorkerPassword({
    workerId: worker.id,
    passwordHash: hashWorkerPassword(nextPassword),
    sessionVersion: normalizeSessionVersion(worker.session_version) + 1,
    now,
  })
  await revokeAllWorkerSessions(worker.id, now)

  return {
    worker: mapWorkerUser(updated || worker),
    reloginRequired: true,
  }
}
