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

vi.mock('@vercel/postgres', () => ({ sql: vi.fn() }));
vi.mock('../../lib/permission-middleware.js', () => ({
  getUserFromRequest: vi.fn(),
}));

import { sql } from '@vercel/postgres';
import { getUserFromRequest } from '../../lib/permission-middleware.js';
import handler from '../../pages/api/user-cards.js';

function createRes() {
  const res = {
    statusCode: 200,
    body: null,
    status(code) {
      res.statusCode = code;
      return res;
    },
    json(data) {
      res.body = data;
      return res;
    },
  };
  return res;
}

describe('POST /api/user-cards', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    getUserFromRequest.mockResolvedValue({ userId: 1, email: 'a@b.c', role: 'user' });
    sql.mockResolvedValue({ rows: [] });
  });

  it('returns 400 when quantity is not a number', async () => {
    const req = {
      method: 'POST',
      body: { cardId: 42, quantity: 'abc' },
    };
    const res = createRes();

    await handler(req, res);

    expect(res.statusCode).toBe(400);
    expect(res.body.error).toBe('Quantity must be at least 1');
    expect(sql).not.toHaveBeenCalled();
  });

  it('returns 400 when quantity is zero', async () => {
    const req = {
      method: 'POST',
      body: { cardId: 42, quantity: 0 },
    };
    const res = createRes();

    await handler(req, res);

    expect(res.statusCode).toBe(400);
    expect(res.body.error).toBe('Quantity must be at least 1');
    expect(sql).not.toHaveBeenCalled();
  });

  it('inserts parsed quantity for a new owned card', async () => {
    sql.mockResolvedValueOnce({ rows: [] });

    const req = {
      method: 'POST',
      body: { cardId: 42, quantity: '3', condition: 'LP', is_foil: true },
    };
    const res = createRes();

    await handler(req, res);

    expect(res.statusCode).toBe(200);
    expect(sql).toHaveBeenCalledTimes(2);
    const insertCall = sql.mock.calls[1];
    expect(insertCall[2]).toBe(42);
    expect(insertCall[3]).toBe(3);
    expect(insertCall[4]).toBe('LP');
    expect(insertCall[5]).toBe(true);
  });
});
