/**
 * AtlasService unit tests
 * Verifies user-image upsert behavior so duplicate metadata rows do not grow
 * over time and stale image paths are surfaced for cleanup.
 */
const AtlasService = require('../../../services/AtlasService');

describe('AtlasService', () => {
    let pool;
    let client;
    let service;

    beforeEach(() => {
        client = {
            query: jest.fn(),
            release: jest.fn(),
        };
        pool = {
            connect: jest.fn().mockResolvedValue(client),
        };
        service = new AtlasService(pool);
    });

    describe('upsertUserImageRecord', () => {
        it('skips adding a new row when the same image content already exists', async () => {
            jest.spyOn(service, 'resolveStoredImageHash').mockReturnValue('same-hash');

            client.query
                .mockResolvedValueOnce({
                    rows: [
                        {
                            id: 7,
                            image_path: '/public/user_added_images/existing.png',
                            image_hash: 'same-hash',
                            original_filename: 'existing.png',
                        },
                    ],
                });

            const result = await service.upsertUserImageRecord(client, {
                optionId: 11,
                imagePath: '/public/user_added_images/new-upload.png',
                isDrawing: false,
                originalFilename: 'renamed.png',
                imageHash: 'same-hash',
            });

            expect(client.query).toHaveBeenCalledTimes(1);
            expect(result).toEqual({
                imagePath: '/public/user_added_images/existing.png',
                replacedImagePaths: ['/public/user_added_images/new-upload.png'],
                skippedDuplicate: true,
            });
        });

        it('updates the newest matching row and removes older duplicates', async () => {
            jest.spyOn(service, 'resolveStoredImageHash').mockImplementation((row) => row.image_hash || null);

            client.query
                .mockResolvedValueOnce({
                    rows: [
                        { id: 7, image_path: '/public/user_added_images/newer.png', image_hash: 'stored-hash', original_filename: 'source.png' },
                        { id: 3, image_path: '/public/user_added_images/older.png', image_hash: 'other-hash', original_filename: 'source.png' },
                    ],
                })
                .mockResolvedValueOnce({ rowCount: 1 })
                .mockResolvedValueOnce({ rowCount: 1 });

            const result = await service.upsertUserImageRecord(client, {
                optionId: 11,
                imagePath: '/public/user_added_images/replacement.png',
                isDrawing: false,
                originalFilename: 'source.png',
                imageHash: 'new-hash',
            });

            expect(client.query).toHaveBeenNthCalledWith(
                1,
                expect.stringContaining('SELECT id, image_path'),
                [11, false]
            );
            expect(client.query).toHaveBeenNthCalledWith(
                2,
                expect.stringContaining('UPDATE user_contributed_images'),
                [7, '/public/user_added_images/replacement.png', 'source.png', 'new-hash']
            );
            expect(client.query).toHaveBeenNthCalledWith(
                3,
                expect.stringContaining('DELETE FROM user_contributed_images'),
                [[3]]
            );
            expect(result).toEqual({
                imagePath: '/public/user_added_images/replacement.png',
                replacedImagePaths: [
                    '/public/user_added_images/newer.png',
                    '/public/user_added_images/older.png',
                ],
                skippedDuplicate: false,
            });
        });

        it('inserts a new row when no matching image exists', async () => {
            client.query
                .mockResolvedValueOnce({ rows: [] })
                .mockResolvedValueOnce({ rowCount: 1 });

            const result = await service.upsertUserImageRecord(client, {
                optionId: 11,
                imagePath: '/public/user_added_images/fresh.png',
                isDrawing: true,
                originalFilename: 'fresh.png',
                imageHash: 'fresh-hash',
            });

            expect(client.query).toHaveBeenNthCalledWith(
                2,
                expect.stringContaining('INSERT INTO user_contributed_images'),
                [11, '/public/user_added_images/fresh.png', true, 'fresh.png', 'fresh-hash']
            );
            expect(result).toEqual({
                imagePath: '/public/user_added_images/fresh.png',
                replacedImagePaths: [],
                skippedDuplicate: false,
            });
        });
    });
});