import { jest } from '@jest/globals'

jest.unstable_mockModule('../cima-service.js', () => ({
  searchMedicines: jest.fn(async () => []),
  getMedicineDetails: jest.fn(async () => null),
  searchOTC: jest.fn(async () => []),
}))

jest.unstable_mockModule('../off-service.js', () => ({
  searchBabyProducts: jest.fn(async () => []),
  getBabyProductDetails: jest.fn(async () => null),
}))

jest.unstable_mockModule('../farmacias-webhook-import.js', () => ({
  runFarmaciaWebhookImport: jest.fn(async () => ({})),
  DEFAULT_FARMACIAS_WEBHOOK: '',
  importPharmaciesFromRows: jest.fn(async () => ({})),
}))

jest.unstable_mockModule('../../API/index.js', () => ({
  fetchPharmaciesExternal: jest.fn(async () => []),
}))

process.env.DATABASE_PATH = ':memory:'
process.env.NODE_ENV = 'test'

const { default: supertest } = await import('supertest')
const { app, initDatabase, db } = await import('../server.js')
const { default: bcrypt } = await import('bcrypt')

beforeAll(async () => {
  await initDatabase()
  const hash = await bcrypt.hash('testpass', 10)
  await new Promise((resolve, reject) => {
    db.run(
      'INSERT INTO users (username, password_hash, is_admin) VALUES (?, ?, 1)',
      ['testadmin', hash],
      (err) => (err ? reject(err) : resolve())
    )
  })
})

describe('Medicine search', () => {
  test('GET /api/medicines/search with empty q returns []', async () => {
    const res = await supertest(app).get('/api/medicines/search?q=')
    expect(res.status).toBe(200)
    expect(res.body).toEqual([])
  })

  test('GET /api/medicines/search with short q returns array', async () => {
    const res = await supertest(app).get('/api/medicines/search?q=a')
    expect(res.status).toBe(200)
    expect(Array.isArray(res.body)).toBe(true)
  })
})

describe('Authentication', () => {
  test('POST /api/auth/login with wrong creds returns 401', async () => {
    const res = await supertest(app)
      .post('/api/auth/login')
      .send({ username: 'nobody', password: 'wrong' })
    expect(res.status).toBe(401)
  })
})

describe('Admin routes', () => {
  test('GET /api/admin/medicines without auth returns 401', async () => {
    const res = await supertest(app).get('/api/admin/medicines')
    expect(res.status).toBe(401)
  })

  test('POST /api/admin/pharmacies with valid auth returns 201', async () => {
    const agent = supertest.agent(app)
    const login = await agent
      .post('/api/auth/login')
      .send({ username: 'testadmin', password: 'testpass' })
    expect(login.status).toBe(200)

    const res = await agent.post('/api/admin/pharmacies').send({
      name: 'Test Pharmacy',
      address: 'Test Street 1',
    })
    expect(res.status).toBe(201)
    expect(res.body).toMatchObject({ name: 'Test Pharmacy', address: 'Test Street 1' })
  })
})
