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

import {
  releaseReservedInventoryItemsWithDeps,
  reserveInventoryForTaskWithDeps,
} from './inventory-service.js'

test('reserveInventoryForTaskWithDeps returns null when skuCode is missing', async () => {
  let findCalled = false

  const result = await reserveInventoryForTaskWithDeps(
    { skuCode: '', taskId: 12 },
    {
      findFirstAvailableInventoryItemBySkuCode: async () => {
        findCalled = true
        return null
      },
    },
  )

  assert.equal(result, null)
  assert.equal(findCalled, false)
})

test('reserveInventoryForTaskWithDeps reserves first available inventory item with defaults', async () => {
  const calls = []
  const result = await reserveInventoryForTaskWithDeps(
    { skuCode: 'dnf-cdk-a', taskId: 88 },
    {
      findFirstAvailableInventoryItemBySkuCode: async (skuCode, credentialType, inventoryGroupCodes) => {
        calls.push(['find', skuCode, credentialType, inventoryGroupCodes])
        return { id: 321 }
      },
      assignReservedInventoryItem: async (inventoryItemId, taskId, updatedAt, roleKey) => {
        calls.push(['assign', inventoryItemId, taskId, updatedAt, roleKey])
        return { id: inventoryItemId, reserved_by_task_id: taskId, role_key: roleKey, updated_at: updatedAt }
      },
      nowIso: () => '2026-04-14T12:00:00.000Z',
    },
  )

  assert.deepEqual(calls, [
    ['find', 'dnf-cdk-a', 'tencent_code', null],
    ['assign', 321, 88, '2026-04-14T12:00:00.000Z', 'primary_code'],
  ])
  assert.equal(result?.id, 321)
  assert.equal(result?.reserved_by_task_id, 88)
})

test('reserveInventoryForTaskWithDeps forwards inventory group filters', async () => {
  const calls = []

  await reserveInventoryForTaskWithDeps(
    { skuCode: 'dnf-cdk-a', taskId: 88, inventoryGroupCodes: ['A组', 'B组'] },
    {
      findFirstAvailableInventoryItemBySkuCode: async (skuCode, credentialType, inventoryGroupCodes) => {
        calls.push(['find', skuCode, credentialType, inventoryGroupCodes])
        return { id: 321 }
      },
      assignReservedInventoryItem: async () => ({ id: 321 }),
      nowIso: () => '2026-04-14T12:00:00.000Z',
    },
  )

  assert.deepEqual(calls, [
    ['find', 'dnf-cdk-a', 'tencent_code', ['A组', 'B组']],
  ])
})

test('reserveInventoryForTaskWithDeps returns null when restricted inventory groups are empty', async () => {
  let findCalled = false

  const result = await reserveInventoryForTaskWithDeps(
    { skuCode: 'dnf-cdk-a', taskId: 12, inventoryGroupCodes: [] },
    {
      findFirstAvailableInventoryItemBySkuCode: async () => {
        findCalled = true
        return null
      },
    },
  )

  assert.equal(result, null)
  assert.equal(findCalled, false)
})

test('releaseReservedInventoryItemsWithDeps skips empty ids and keeps successful releases only', async () => {
  const calls = []
  const result = await releaseReservedInventoryItemsWithDeps(
    [0, null, 11, 12, '', 13],
    '2026-04-14T13:00:00.000Z',
    {
      releaseReservedInventoryItem: async (inventoryItemId, updatedAt) => {
        calls.push([inventoryItemId, updatedAt])
        return inventoryItemId === 12 ? null : { id: inventoryItemId }
      },
    },
  )

  assert.deepEqual(calls, [
    [11, '2026-04-14T13:00:00.000Z'],
    [12, '2026-04-14T13:00:00.000Z'],
    [13, '2026-04-14T13:00:00.000Z'],
  ])
  assert.deepEqual(result, [
    { id: 11 },
    { id: 13 },
  ])
})
