import { describe, it, expect, beforeAll, afterAll, afterEach } from 'vitest'
import { http, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'
import { updateUserPermisosOverrides } from '../../../features/users/api/updateUserPermisosOverrides'

const API_URL = 'http://localhost:5000'

const mockResponse = {
  rolPermisos: ['ventas:contado:crear'],
  overrides: {
    grant: ['textos:editar'],
    deny: [],
  },
  effective: ['ventas:contado:crear', 'textos:editar'],
}

const server = setupServer()

beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))
afterEach(() => server.resetHandlers())
afterAll(() => server.close())

describe('updateUserPermisosOverrides api client', () => {
  it('calls PUT /api/v1/users/:id/permisos/overrides with correct body and returns UsuarioPermisos', async () => {
    let capturedBody: unknown = null
    server.use(
      http.put(`${API_URL}/api/v1/users/42/permisos/overrides`, async ({ request }) => {
        capturedBody = await request.json()
        return HttpResponse.json(mockResponse)
      }),
    )

    const result = await updateUserPermisosOverrides(42, {
      grant: ['textos:editar'],
      deny: [],
    })

    expect(result.overrides.grant).toEqual(['textos:editar'])
    expect(result.effective).toContain('textos:editar')
    expect(capturedBody).toMatchObject({ grant: ['textos:editar'], deny: [] })
  })

  it('rejects on 400 invalid-permiso-codes', async () => {
    server.use(
      http.put(`${API_URL}/api/v1/users/42/permisos/overrides`, () =>
        HttpResponse.json(
          { title: 'invalid-permiso-codes', status: 400, invalidCodes: ['modulo:fake:accion'] },
          { status: 400 },
        ),
      ),
    )

    await expect(
      updateUserPermisosOverrides(42, { grant: ['modulo:fake:accion'], deny: [] }),
    ).rejects.toThrow()
  })

  it('rejects on 400 grant-deny-overlap', async () => {
    server.use(
      http.put(`${API_URL}/api/v1/users/42/permisos/overrides`, () =>
        HttpResponse.json(
          { title: 'grant-deny-overlap', status: 400, overlap: ['textos:editar'] },
          { status: 400 },
        ),
      ),
    )

    await expect(
      updateUserPermisosOverrides(42, { grant: ['textos:editar'], deny: ['textos:editar'] }),
    ).rejects.toThrow()
  })
})
