import test from 'node:test'
import assert from 'node:assert/strict'

import {
  buildOpen91SignSource,
  encryptOpen91Cards,
  signOpen91Payload,
  verifyOpen91Signature,
} from './crypto.js'
import { buildOpen91CardItem, formatOpen91ExpireTime, resolveOpen91QueryState } from './response.js'

test('signOpen91Payload signs only request body fields', () => {
  const config = {
    userId: '1001',
    secret: 'rste57w8rsubsnxsb384ur3u9kn5fzhr',
  }
  const payload = {
    orderNo: 'P91KS202605040001',
    productNo: 'KS-CLOUD-SKU-001',
    buyNum: 1,
    maxAmount: '0.0000',
    callbackUrl: 'https://cb.example.com/notify/91/order',
    timestamp: 1777867200,
    version: '1.0',
  }

  const source = buildOpen91SignSource(payload, config)
  assert.equal(
    source,
    'rste57w8rsubsnxsb384ur3u9kn5fzhrbuyNum=1&callbackUrl=https://cb.example.com/notify/91/order&maxAmount=0.0000&orderNo=P91KS202605040001&productNo=KS-CLOUD-SKU-001&timestamp=1777867200&version=1.0rste57w8rsubsnxsb384ur3u9kn5fzhr',
  )

  const sign = signOpen91Payload(payload, config)
  assert.equal(sign.length, 32)
  assert.equal(verifyOpen91Signature({ ...payload, sign }, config), true)
})

test('signOpen91Payload does not add missing optional fields or configured userId', () => {
  const config = {
    userId: '1001',
    secret: 'rste57w8rsubsnxsb384ur3u9kn5fzhr',
  }
  const payload = {
    orderNo: '2613300083829561',
    productNo: '183999074510936',
    buyNum: 1,
    maxAmount: '0.01',
    timestamp: 1778670308,
    version: '1.0',
  }

  assert.equal(
    buildOpen91SignSource(payload, config),
    'rste57w8rsubsnxsb384ur3u9kn5fzhrbuyNum=1&maxAmount=0.01&orderNo=2613300083829561&productNo=183999074510936&timestamp=1778670308&version=1.0rste57w8rsubsnxsb384ur3u9kn5fzhr',
  )
})

test('encryptOpen91Cards matches documented AES ECB base64 sample', () => {
  const cards = [
    {
      cardNo: '10001',
      cardPwd: '123456',
      expireTime: '2023-06-19 17:16:01',
    },
  ]

  assert.equal(
    encryptOpen91Cards(cards, '0a091b3aa4324435aab703142518a8f7'),
    '34APdvSJhWfr5wnzE4YzxAsI0gfI6pI/Njrj1UQMHJrZ8Dq9EWsDnln0pp08gn4KES4iQu9/f0Y8UMN4dGdSK67oi0Bc12/V8hrNxqoC3Lk=',
  )
})

test('resolveOpen91QueryState returns success only when every task is ready', () => {
  assert.deepEqual(
    resolveOpen91QueryState({
      tasks: [
        { id: 1, task_status: 'pending_binding_prepare' },
        { id: 2, task_status: 'waiting_binding' },
      ],
      readyTaskIds: [1, 2],
    }),
    {
      orderStatus: 20,
      failCode: 0,
      failReason: '',
    },
  )

  assert.deepEqual(
    resolveOpen91QueryState({
      tasks: [
        { id: 1, task_status: 'pending_binding_prepare' },
        { id: 2, task_status: 'waiting_binding' },
      ],
      readyTaskIds: [1],
    }),
    {
      orderStatus: 10,
      failCode: 0,
      failReason: '',
    },
  )

  assert.deepEqual(
    resolveOpen91QueryState({
      tasks: [{ id: 1, task_status: 'manual_review', last_error: '商品未配置' }],
      readyTaskIds: [],
    }),
    {
      orderStatus: 30,
      failCode: 1204,
      failReason: '商品未配置',
    },
  )
})

test('buildOpen91CardItem mirrors claim link into jumpLink and leaves password empty', () => {
  assert.deepEqual(
    buildOpen91CardItem({
      claimUrl: 'https://example.com/#/claim/abc123xyz',
      expireTime: '2026-05-05 12:00:00',
    }),
    {
      cardNo: 'https://example.com/#/claim/abc123xyz',
      cardPwd: '',
      expireTime: '2026-05-05 12:00:00',
      jumpLink: 'https://example.com/#/claim/abc123xyz',
    },
  )
})

test('formatOpen91ExpireTime keeps 91-compatible values and normalizes dates to Beijing time', () => {
  assert.equal(formatOpen91ExpireTime('2026-05-05 12:00:00'), '2026-05-05 12:00:00')
  assert.equal(formatOpen91ExpireTime('1778674551'), '1778674551')
  assert.equal(formatOpen91ExpireTime(new Date('2026-05-14T12:15:51.842Z')), '2026-05-14 20:15:51')
})
