import { BadRequestException, UnauthorizedException } from '@nestjs/common';
import { ReceiptImportController } from './receipt-import.controller';

describe('ReceiptImport controller security', () => {
  const receiptImportServiceMock = {
    parseReceipt: jest.fn(),
    upsertUnitMapping: jest.fn(),
    saveReceipt: jest.fn(),
  };

  const controller = new ReceiptImportController(receiptImportServiceMock as any);

  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('parseReceipt nekar när fil saknas', async () => {
    await expect(controller.parseReceipt(undefined, { user: { id: 1 } })).rejects.toThrow(BadRequestException);
  });

  it('parseReceipt nekar otillåten mime-type', async () => {
    const file = { buffer: Buffer.from('x'), mimetype: 'text/plain' } as any;

    await expect(controller.parseReceipt(file, { user: { id: 1 } })).rejects.toThrow(BadRequestException);
  });

  it('parseReceipt vidarebefordrar premium/admin och userId', async () => {
    const file = { buffer: Buffer.from('x'), mimetype: 'image/jpeg' } as any;
    receiptImportServiceMock.parseReceipt.mockResolvedValue([]);

    await controller.parseReceipt(file, { user: { id: 42, role: 'admin', isPremium: false } });

    expect(receiptImportServiceMock.parseReceipt).toHaveBeenCalledWith(file, true, 42);
  });

  it('upsertUnitMapping använder req.user.id när tillgänglig', async () => {
    receiptImportServiceMock.upsertUnitMapping.mockResolvedValue({ ok: true });

    await controller.upsertUnitMapping(
      { productId: 1, originalUnit: 'g', preferredUnit: 'kg' } as any,
      { user: { id: 42 } },
    );

    expect(receiptImportServiceMock.upsertUnitMapping).toHaveBeenCalledWith(42, 1, 'g', 'kg');
  });

  it('upsertUnitMapping fallbackar till req.user.userId', async () => {
    receiptImportServiceMock.upsertUnitMapping.mockResolvedValue({ ok: true });

    await controller.upsertUnitMapping(
      { productId: 1, originalUnit: 'g', preferredUnit: 'kg' } as any,
      { user: { userId: 99 } },
    );

    expect(receiptImportServiceMock.upsertUnitMapping).toHaveBeenCalledWith(99, 1, 'g', 'kg');
  });

  it('upsertUnitMapping nekar när användar-id saknas', async () => {
    await expect(
      controller.upsertUnitMapping({ productId: 1, originalUnit: 'g', preferredUnit: 'kg' } as any, { user: {} }),
    ).rejects.toThrow(UnauthorizedException);
  });

  it('saveReceipt nekar global alias för icke-admin', async () => {
    const dto = {
      items: [{ learnAliasGlobally: true }],
    };

    await expect(controller.saveReceipt(dto as any, { user: { id: 42, role: 'user' } })).rejects.toThrow(
      BadRequestException,
    );

    expect(receiptImportServiceMock.saveReceipt).not.toHaveBeenCalled();
  });

  it('saveReceipt tillåter global alias för admin', async () => {
    const dto = {
      items: [{ learnAliasGlobally: true }],
    };
    receiptImportServiceMock.saveReceipt.mockResolvedValue({ success: true });

    await controller.saveReceipt(dto as any, { user: { userId: 42, role: 'admin' } });

    expect(receiptImportServiceMock.saveReceipt).toHaveBeenCalledWith(42, dto);
  });
});
