import { beforeEach, describe, expect, it, vi } from 'vitest'

const getMock = vi.fn()
const postMock = vi.fn()
const putMock = vi.fn()
const delMock = vi.fn()

vi.mock('@/lib/http/client', () => ({
  get: getMock,
  post: postMock,
  put: putMock,
  del: delMock,
}))

describe('devices service', () => {
  beforeEach(() => {
    getMock.mockReset()
    postMock.mockReset()
    putMock.mockReset()
    delMock.mockReset()
  })

  it('lists user devices', async () => {
    const { listDevices } = await import('./devices')
    await listDevices({ page: 1, page_size: 10 })

    expect(getMock).toHaveBeenCalledWith('/devices', { page: 1, page_size: 10 })
  })

  it('lists all devices for admin', async () => {
    const { listAllDevices } = await import('./devices')
    await listAllDevices({ page: 1, page_size: 20, status: 1 })

    expect(getMock).toHaveBeenCalledWith('/admin/devices', { page: 1, page_size: 20, status: 1 })
  })

  it('gets a single device by id', async () => {
    const { getDevice } = await import('./devices')
    await getDevice(5)

    expect(getMock).toHaveBeenCalledWith('/devices/5')
  })

  it('deletes a user device', async () => {
    const { deleteDevice } = await import('./devices')
    await deleteDevice(3)

    expect(delMock).toHaveBeenCalledWith('/devices/3')
  })

  it('deletes a device by admin', async () => {
    const { adminDeleteDevice } = await import('./devices')
    await adminDeleteDevice(7)

    expect(delMock).toHaveBeenCalledWith('/admin/devices/7')
  })

  it('updates device status', async () => {
    const { updateDeviceStatus } = await import('./devices')
    await updateDeviceStatus(2, 1)

    expect(putMock).toHaveBeenCalledWith('/devices/2/status', { status: 1 })
  })

  it('updates device status by admin', async () => {
    const { adminUpdateDeviceStatus } = await import('./devices')
    await adminUpdateDeviceStatus(4, 0)

    expect(putMock).toHaveBeenCalledWith('/admin/devices/4/status', { status: 0 })
  })

  it('trusts a device', async () => {
    const { trustDevice } = await import('./devices')
    await trustDevice(1, '30d')

    expect(postMock).toHaveBeenCalledWith('/devices/1/trust', { trust_duration: '30d' })
  })

  it('trusts a device by admin', async () => {
    const { adminTrustDevice } = await import('./devices')
    await adminTrustDevice(6, '7d')

    expect(postMock).toHaveBeenCalledWith('/admin/devices/6/trust', { trust_duration: '7d' })
  })

  it('trusts a device by device id string', async () => {
    const { trustDeviceByDeviceId } = await import('./devices')
    await trustDeviceByDeviceId('device-abc-123', '30d')

    expect(postMock).toHaveBeenCalledWith(
      '/devices/by-device-id/device-abc-123/trust',
      { trust_duration: '30d' },
    )
  })

  it('untrusts a device', async () => {
    const { untrustDevice } = await import('./devices')
    await untrustDevice(2)

    expect(delMock).toHaveBeenCalledWith('/devices/2/trust')
  })

  it('untrusts a device by admin', async () => {
    const { adminUntrustDevice } = await import('./devices')
    await adminUntrustDevice(8)

    expect(delMock).toHaveBeenCalledWith('/admin/devices/8/trust')
  })

  it('gets my trusted devices', async () => {
    const { getMyTrustedDevices } = await import('./devices')
    await getMyTrustedDevices()

    expect(getMock).toHaveBeenCalledWith('/devices/me/trusted')
  })

  it('logs out other devices', async () => {
    const { logoutOtherDevices } = await import('./devices')
    await logoutOtherDevices('current-device-id')

    expect(postMock).toHaveBeenCalledWith('/devices/me/logout-others', {
      current_device_id: 'current-device-id',
    })
  })
})
