import {
  createWorkerWithdrawalAccount as createWorkerWithdrawalAccountRecord,
  getWorkerWithdrawalAccount,
  upsertWorkerWithdrawalAccount,
} 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 { refreshUploadedFileUrls } from '../file-storage/file-storage-service.js'
import { normalizeProofFiles, normalizeWithdrawChannel } from './mappers.js'
import {
  getRequiredWorker,
  requireActiveWorkerSession,
  type WorkerSession,
} from './worker-session-context-service.js'

export async function createWorkerWithdrawalAccount(
  payload: JsonObject = {},
  session: WorkerSession,
) {
  requireActiveWorkerSession(session)
  const worker = await getRequiredWorker(session.workerId)
  const accountChannel = normalizeWithdrawChannel(payload.accountChannel || payload.channel)
  const existing = await getWorkerWithdrawalAccount(worker.id, accountChannel)
  if (existing) {
    throw createHttpError('该提现方式的信息已添加，修改请联系客服处理', {
      statusCode: 409,
      errorCode: 'worker_withdrawal_account_already_set',
    })
  }

  const accountName = String(payload.accountName || payload.realName || '').trim()
  const accountNo =
    accountChannel === 'alipay' ? String(payload.accountNo || payload.account || '').trim() : ''
  const alipayQrCodeImage =
    accountChannel === 'alipay'
      ? normalizeProofFiles(payload.alipayQrCodeImages || payload.alipayQrCodes)[0] || null
      : null
  const wechatQrCodeImage =
    accountChannel === 'wechat'
      ? normalizeProofFiles(payload.wechatQrCodeImages || payload.wechatQrCodes)[0] || null
      : null
  if (!accountName) {
    throw createHttpError('请填写收款人姓名', {
      statusCode: 400,
      errorCode: 'worker_withdraw_account_name_required',
    })
  }
  if (accountChannel === 'alipay' && !accountNo) {
    throw createHttpError('请填写收款账号', {
      statusCode: 400,
      errorCode: 'worker_withdraw_account_no_required',
    })
  }
  if (accountChannel === 'alipay' && !alipayQrCodeImage) {
    throw createHttpError('请上传支付宝收款二维码', {
      statusCode: 400,
      errorCode: 'worker_withdraw_alipay_qr_required',
    })
  }
  if (accountChannel === 'wechat' && !wechatQrCodeImage) {
    throw createHttpError('请上传微信收款二维码', {
      statusCode: 400,
      errorCode: 'worker_withdraw_wechat_qr_required',
    })
  }

  const created = await createWorkerWithdrawalAccountRecord({
    workerId: worker.id,
    accountChannel,
    accountName,
    accountNo,
    alipayQrCodeJson: JSON.stringify(alipayQrCodeImage || {}),
    wechatQrCodeJson: JSON.stringify(wechatQrCodeImage || {}),
    now: nowIso(),
  })
  if (!created) {
    throw createHttpError('该提现方式的信息已添加，修改请联系客服处理', {
      statusCode: 409,
      errorCode: 'worker_withdrawal_account_already_set',
    })
  }
  return {
    withdrawalAccount: mapWithdrawalAccount(created),
  }
}

/** 历史支付宝账户只允许补充一次收款二维码，不允许修改账户姓名、账号或二维码。 */
export async function saveWorkerAlipayWithdrawalQrCode(
  payload: JsonObject = {},
  session: WorkerSession,
) {
  requireActiveWorkerSession(session)
  const worker = await getRequiredWorker(session.workerId)
  const current = await getWorkerWithdrawalAccount(worker.id, 'alipay')
  if (!current) {
    throw createHttpError('请先添加支付宝提现信息', {
      statusCode: 409,
      errorCode: 'worker_withdrawal_alipay_account_required',
    })
  }
  if (resolveAlipayWithdrawalQrCode(current)) {
    throw createHttpError('支付宝收款二维码已补充，后续修改请联系客服处理', {
      statusCode: 409,
      errorCode: 'worker_withdrawal_alipay_qr_already_set',
    })
  }
  const alipayQrCodeImage = normalizeProofFiles(
    payload.alipayQrCodeImages || payload.alipayQrCodes,
  )[0]
  if (!alipayQrCodeImage) {
    throw createHttpError('请上传支付宝收款二维码', {
      statusCode: 400,
      errorCode: 'worker_withdraw_alipay_qr_required',
    })
  }
  const saved = await upsertWorkerWithdrawalAccount({
    workerId: worker.id,
    accountChannel: 'alipay',
    accountName: current.account_name,
    accountNo: current.account_no,
    alipayQrCodeJson: JSON.stringify(alipayQrCodeImage),
    wechatQrCodeJson: JSON.stringify(safeParseJson(current.wechat_qr_code_json)),
    now: nowIso(),
  })
  if (!saved) {
    throw createHttpError('保存支付宝收款二维码失败', {
      statusCode: 500,
      errorCode: 'worker_withdrawal_alipay_qr_save_failed',
    })
  }
  return { withdrawalAccount: mapWithdrawalAccount(saved) }
}

export function mapWithdrawalAccount(account: {
  account_channel: string
  account_name: string
  account_no: string
  alipay_qr_code_json: string | Record<string, unknown>
  wechat_qr_code_json: string | Record<string, unknown>
  created_at: string
}) {
  const alipayQrCodeImage = resolveAlipayWithdrawalQrCode(account)
  const wechatQrCodeImage = resolveWechatWithdrawalQrCode(account)
  return {
    accountChannel: account.account_channel,
    accountName: account.account_name,
    accountNoMasked:
      account.account_channel === 'alipay' ? maskWithdrawalAccountNo(account.account_no) : '',
    alipayQrCodeImage,
    wechatQrCodeImage,
    createdAt: account.created_at,
  }
}

export function resolveAlipayWithdrawalQrCode(account: {
  alipay_qr_code_json: string | Record<string, unknown>
}) {
  const file = refreshUploadedFileUrls(safeParseJson(account.alipay_qr_code_json))
  return String(file.url || '').trim() ? file : null
}

export function resolveWechatWithdrawalQrCode(account: {
  wechat_qr_code_json: string | Record<string, unknown>
}) {
  const file = refreshUploadedFileUrls(safeParseJson(account.wechat_qr_code_json))
  return String(file.url || '').trim() ? file : null
}

function maskWithdrawalAccountNo(accountNo: string) {
  const normalized = String(accountNo || '').trim()
  if (normalized.length <= 4) return normalized
  return `${'*'.repeat(Math.max(4, normalized.length - 4))}${normalized.slice(-4)}`
}
