import { BadRequestException, ServiceUnavailableException } from '@nestjs/common';
import { QuickImportService } from './quick-import.service';

jest.mock('../common/utils/download-image', () => ({
  downloadAndOptimizeImage: jest.fn(),
}));

const { downloadAndOptimizeImage } = jest.requireMock('../common/utils/download-image') as {
  downloadAndOptimizeImage: jest.Mock;
};

describe('QuickImportService flow', () => {
  let service: QuickImportService;

  beforeEach(() => {
    jest.clearAllMocks();
    service = new QuickImportService();
  });

  it('importFromInput: delegerar till importer och laddar ner extern bild lokalt', async () => {
    (global as any).fetch = jest.fn().mockResolvedValue({
      ok: true,
      json: async () => ({
        markdown: '# Lasagne',
        source: 'other',
        imageUrl: 'https://cdn.example.com/lasagne.jpg',
      }),
    });

    downloadAndOptimizeImage.mockResolvedValue('/app/recipe-images/lasagne.jpg');

    const result = await service.importFromInput('https://www.ica.se/recept/lasagne');

    expect((global as any).fetch).toHaveBeenCalledTimes(1);
    expect((global as any).fetch).toHaveBeenCalledWith(
      expect.stringContaining('/api/quick-import'),
      expect.objectContaining({
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
      }),
    );
    expect(downloadAndOptimizeImage).toHaveBeenCalledWith(
      'https://cdn.example.com/lasagne.jpg',
      expect.any(String),
    );
    expect(result.imageUrl).toBe('/app/recipe-images/lasagne.jpg');
  });

  it('importFromUpload: skickar form-data och behåller imageUrl när den redan är lokal', async () => {
    (global as any).fetch = jest.fn().mockResolvedValue({
      ok: true,
      json: async () => ({
        markdown: '# Köttfärssås',
        source: 'image',
        imageUrl: '/app/recipe-images/local.jpg',
      }),
    });

    const file = {
      buffer: Buffer.from('img'),
      mimetype: 'image/jpeg',
      originalname: 'receipt.jpg',
    } as any;

    const result = await service.importFromUpload(file);

    expect((global as any).fetch).toHaveBeenCalledTimes(1);
    expect(downloadAndOptimizeImage).not.toHaveBeenCalled();
    expect(result.imageUrl).toBe('/app/recipe-images/local.jpg');
  });

  it('importFromInput: kastar BadRequestException vid tom input', async () => {
    await expect(service.importFromInput('   ')).rejects.toBeInstanceOf(BadRequestException);
  });

  it('importFromInput: mappar importer 4xx till BadRequestException', async () => {
    (global as any).fetch = jest.fn().mockResolvedValue({
      ok: false,
      status: 400,
      json: async () => ({ message: 'Ogiltig URL' }),
    });

    await expect(service.importFromInput('hej')).rejects.toBeInstanceOf(BadRequestException);
  });

  it('importFromUpload: mappar nätverksfel till ServiceUnavailableException', async () => {
    (global as any).fetch = jest.fn().mockRejectedValue(new Error('ECONNREFUSED'));

    const file = {
      buffer: Buffer.from('img'),
      mimetype: 'image/jpeg',
      originalname: 'receipt.jpg',
    } as any;

    await expect(service.importFromUpload(file)).rejects.toBeInstanceOf(ServiceUnavailableException);
  });

  it('lägger imageWarning när bildnedladdning misslyckas', async () => {
    (global as any).fetch = jest.fn().mockResolvedValue({
      ok: true,
      json: async () => ({
        markdown: '# Recept',
        source: 'other',
        imageUrl: 'https://cdn.example.com/recept.jpg',
      }),
    });

    downloadAndOptimizeImage.mockRejectedValue(new Error('timeout'));

    const result = await service.importFromInput('https://example.com/recept');

    expect(result.imageUrl).toBe('https://cdn.example.com/recept.jpg');
    expect(result.imageWarning).toContain('Receptbild kunde inte laddas ner lokalt');
  });
});
