const test = require('node:test');
const assert = require('assert');
const { app } = require('../app');

test('GET /offers should return offers', async () => {
  const response = await app.inject({
    method: 'GET',
    url: '/offers'
  });
  assert.strictEqual(response.statusCode, 200);
  assert.strictEqual(response.headers['content-type'], 'application/json; charset=utf-8');
});

test('POST /offers/:requestId should create a new offer with valid data', async () => {
  const response = await app.inject({
    method: 'POST',
    url: '/offers/1',
    payload: {
      amountChf: 50,
      message: 'I can help with this'
    }
  });
  assert.strictEqual(response.statusCode, 201);
});

test('POST /offers/:requestId should return 400 for invalid requestId', async () => {
  const response = await app.inject({
    method: 'POST',
    url: '/offers/invalid',
    payload: {
      amountChf: 50,
      message: 'I can help with this'
    }
  });
  assert.strictEqual(response.statusCode, 400);
});

test('POST /offers/:requestId should return 400 for invalid payload', async () => {
  const response = await app.inject({
    method: 'POST',
    url: '/offers/1',
    payload: {
      amountChf: -50,
      message: 'I can help with this'
    }
  });
  assert.strictEqual(response.statusCode, 400);
});

test('POST /offers/negotiation/:offerId should create a new negotiation with valid data', async () => {
  const response = await app.inject({
    method: 'POST',
    url: '/offers/negotiation/1',
    payload: {
      amountChf: 60,
      message: 'What about this amount?'
    }
  });
  assert.strictEqual(response.statusCode, 201);
});

test('POST /offers/negotiation/:offerId should return 400 for invalid offerId', async () => {
  const response = await app.inject({
    method: 'POST',
    url: '/offers/negotiation/invalid',
    payload: {
      amountChf: 60,
      message: 'What about this amount?'
    }
  });
  assert.strictEqual(response.statusCode, 400);
});

test('POST /offers/negotiation/:offerId should return 400 for invalid payload', async () => {
  const response = await app.inject({
    method: 'POST',
    url: '/offers/negotiation/1',
    payload: {
      amountChf: -60,
      message: 'What about this amount?'
    }
  });
  assert.strictEqual(response.statusCode, 400);
});

test('POST /offers/accept/:offerId should accept an offer and create a deal', async () => {
  const response = await app.inject({
    method: 'POST',
    url: '/offers/accept/1',
    payload: {}
  });
  assert.strictEqual(response.statusCode, 201);
});

test('POST /offers/accept/:offerId should return 404 for non-existent offer', async () => {
  const response = await app.inject({
    method: 'POST',
    url: '/offers/accept/999',
    payload: {}
  });
  assert.strictEqual(response.statusCode, 404);
});

// Additional test for validation of message length
test('POST /offers/:requestId should return 400 for message exceeding max length', async () => {
  const longMessage = 'a'.repeat(2001); // 2001 characters
  const response = await app.inject({
    method: 'POST',
    url: '/offers/1',
    payload: {
      amountChf: 50,
      message: longMessage
    }
  });
  assert.strictEqual(response.statusCode, 400);
});

// Additional test for validation of negotiation message length
test('POST /offers/negotiation/:offerId should return 400 for message exceeding max length', async () => {
  const longMessage = 'a'.repeat(2001); // 2001 characters
  const response = await app.inject({
    method: 'POST',
    url: '/offers/negotiation/1',
    payload: {
      amountChf: 60,
      message: longMessage
    }
  });
  assert.strictEqual(response.statusCode, 400);
});

// Test for missing authentication
test('POST /offers/:requestId should return 401 for unauthenticated request', async () => {
  const response = await app.inject({
    method: 'POST',
    url: '/offers/1',
    payload: {
      amountChf: 50,
      message: 'I can help with this'
    }
  });
  assert.strictEqual(response.statusCode, 401);
});

// Test for missing authentication in negotiation
test('POST /offers/negotiation/:offerId should return 401 for unauthenticated request', async () => {
  const response = await app.inject({
    method: 'POST',
    url: '/offers/negotiation/1',
    payload: {
      amountChf: 60,
      message: 'What about this amount?'
    }
  });
  assert.strictEqual(response.statusCode, 401);
});

// Test for missing authentication in accept
test('POST /offers/accept/:offerId should return 401 for unauthenticated request', async () => {
  const response = await app.inject({
    method: 'POST',
    url: '/offers/accept/1',
    payload: {}
  });
  assert.strictEqual(response.statusCode, 401);
});