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

// Use hoist-safe factories for vi.mock
vi.mock('$lib/ae_api/api', () => ({
    api: {
        create_nested_obj: vi.fn(),
        update_nested_obj: vi.fn(),
        delete_nested_ae_obj: vi.fn(),
        search_ae_obj: vi.fn()
    }
}));
vi.mock('$lib/ae_core/core__idb_dexie', () => ({
    db_save_ae_obj_li__ae_obj: vi.fn()
}));
vi.mock('$lib/ae_events/db_events', () => ({
    db_events: { badge: { get: vi.fn(), delete: vi.fn() } }
}));
vi.mock('$lib/ae_events/ae_events__event_badge_template', () => ({
    load_ae_obj_id__event_badge_template: vi.fn()
}));

import { create_ae_obj__event_badge } from './ae_events__event_badge';

describe('create_ae_obj__event_badge', () => {
    it('calls api.create_nested_obj with the correct params and returns the result', async () => {
        const mocked = await import('$lib/ae_api/api');
        const mockCreateNested = mocked.api.create_nested_obj as any;

        const fakeResult = { event_badge_id: 'eb123', full_name: 'Test User' };
        mockCreateNested.mockResolvedValue(fakeResult);

        const api_cfg = { base_url: 'http://localhost', headers: {} };
        const event_id = 'evt1';
        const data_kv = {
            full_name_override: 'Test User',
            email: 't@example.com'
        };

        const result = await create_ae_obj__event_badge({
            api_cfg,
            event_id,
            data_kv,
            try_cache: false
        });

        expect(mockCreateNested).toHaveBeenCalled();
        expect(mockCreateNested).toHaveBeenCalledWith({
            api_cfg,
            parent_type: 'event_person',
            parent_id: event_id,
            child_type: 'event_badge',
            fields: data_kv,
            params: {},
            log_lvl: 0
        });

        expect(result).toEqual(fakeResult);
    });
});

describe('update_ae_obj__event_badge', () => {
    it('calls api.update_nested_obj with correct params and returns result', async () => {
        const mocked = await import('$lib/ae_api/api');
        const mockUpdate = mocked.api.update_nested_obj as any;
        const fakeResult = { event_badge_id: 'eb999', full_name: 'Updated' };
        mockUpdate.mockResolvedValue(fakeResult);

        const { update_ae_obj__event_badge } =
            await import('./ae_events__event_badge');
        const api_cfg = { base_url: 'http://localhost', headers: {} };
        const res = await update_ae_obj__event_badge({
            api_cfg,
            event_id: 'evt1',
            event_badge_id: 'eb999',
            data_kv: { full_name_override: 'Updated' },
            try_cache: false
        });

        expect(mockUpdate).toHaveBeenCalled();
        expect(mockUpdate).toHaveBeenCalledWith({
            api_cfg,
            parent_type: 'event',
            parent_id: 'evt1',
            child_type: 'event_badge',
            child_id: 'eb999',
            fields: { full_name_override: 'Updated' },
            params: {},
            log_lvl: 0
        });
        expect(res).toEqual(fakeResult);
    });
});

describe('delete_ae_obj_id__event_badge', () => {
    it('calls api.delete_nested_ae_obj and deletes from local DB when try_cache true', async () => {
        const mocked = await import('$lib/ae_api/api');
        const mockDelete = mocked.api.delete_nested_ae_obj as any;
        mockDelete.mockResolvedValue({ success: true });

        const db = await import('$lib/ae_events/db_events');
        const dbDelete = db.db_events.badge.delete as any;

        const { delete_ae_obj_id__event_badge } =
            await import('./ae_events__event_badge');

        const api_cfg = { base_url: 'http://localhost', headers: {} };
        const res = await delete_ae_obj_id__event_badge({
            api_cfg,
            event_id: 'evt1',
            event_badge_id: 'ebDel',
            try_cache: true
        });

        expect(mockDelete).toHaveBeenCalled();
        expect(dbDelete).toHaveBeenCalledWith('ebDel');
        expect(res).toEqual({ success: true });
    });
});

describe('search__event_badge', () => {
    it('calls api.search_ae_obj and returns list (handles data envelope)', async () => {
        const mocked = await import('$lib/ae_api/api');
        const mockSearch = mocked.api.search_ae_obj as any;
        const fakeList = [{ event_badge_id: 'eb1' }, { event_badge_id: 'eb2' }];
        mockSearch.mockResolvedValue({ data: fakeList });

        const { search__event_badge } =
            await import('./ae_events__event_badge');
        const api_cfg = { base_url: 'http://localhost', headers: {} };
        const res = await search__event_badge({
            api_cfg,
            event_id: 'evt1',
            fulltext_search_qry_str: 'Test',
            try_cache: false
        });

        expect(mockSearch).toHaveBeenCalled();
        expect(Array.isArray(res)).toBe(true);
        expect((res as any).length).toBe(2);
    });
});
