import { nextTick, watchEffect } from 'vue';

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

import { useChatImageUploads } from './useChatImageUploads';

const mediaApi = vi.hoisted(() => ({
  deleteAgentChatImage: vi.fn(),
  uploadAgentChatImage: vi.fn(),
}));

vi.mock('./mediaApi', () => mediaApi);

describe('useChatImageUploads', () => {
  afterEach(() => {
    vi.restoreAllMocks();
    mediaApi.deleteAgentChatImage.mockReset();
    mediaApi.uploadAgentChatImage.mockReset();
  });

  it('reactively exposes the ready state after upload', async () => {
    let resolveUpload: (value: any) => void = () => undefined;
    mediaApi.uploadAgentChatImage.mockReturnValue(
      new Promise((resolve) => {
        resolveUpload = resolve;
      }),
    );
    vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:test-image');
    vi.spyOn(URL, 'revokeObjectURL').mockImplementation(() => undefined);

    const uploads = useChatImageUploads();
    const observedStatuses: (string | undefined)[] = [];
    const stop = watchEffect(() => {
      observedStatuses.push(uploads.items.value[0]?.status);
    });
    const pending = uploads.addFiles(
      [new File(['image'], 'test.png', { type: 'image/png' })],
      { agentId: 'agent-1', mode: 'FORMAL', sessionId: 'session-1' },
    );
    await nextTick();

    resolveUpload({
      data: {
        height: 1,
        mimeType: 'image/png',
        name: 'test.png',
        previewUrl: '/api/v1/agent/media/content?reference=draft%3Atest',
        size: 5,
        uploadId: 'upload-1',
        width: 1,
      },
      errorCode: 0,
    });
    await pending;
    await nextTick();
    stop();

    expect(observedStatuses).toContain('uploading');
    expect(observedStatuses.at(-1)).toBe('ready');
    expect(uploads.uploadIds.value).toEqual(['upload-1']);
  });
});
