// File: frontend/components/admin/ai/__tests__/SandboxTestArea.test.tsx
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import SandboxTestArea from '../SandboxTestArea';

const mockSubmitSandboxOcr = vi.fn();
const mockSubmitSandboxAiExtract = vi.fn();
const mockSubmitSandboxRagPrep = vi.fn();
const mockGetSandboxJobStatus = vi.fn();

vi.mock('@/lib/services/admin-ai.service', () => ({
  adminAiService: {
    submitSandboxOcr: (...args: any) => mockSubmitSandboxOcr(...args),
    submitSandboxAiExtract: (...args: any) => mockSubmitSandboxAiExtract(...args),
    submitSandboxRagPrep: (...args: any) => mockSubmitSandboxRagPrep(...args),
    getSandboxJobStatus: (...args: any) => mockGetSandboxJobStatus(...args),
  },
}));

vi.mock('@/hooks/use-master-data', () => ({
  useProjects: vi.fn(() => ({ data: [{ publicId: 'proj-1', projectCode: 'P1', projectName: 'Project 1' }] })),
  useContracts: vi.fn(() => ({ data: [] })),
}));

vi.mock('sonner', () => ({
  toast: {
    success: vi.fn(),
    error: vi.fn(),
  },
}));

// ResizeObserver mock is needed for Radix UI select
class ResizeObserver {
  observe() {}
  unobserve() {}
  disconnect() {}
}
window.ResizeObserver = ResizeObserver;

describe('SandboxTestArea', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    window.PointerEvent = MouseEvent as any;
  });

  it('renders correctly', async () => {
    render(<SandboxTestArea promptType="ocr_extraction" />);
    
    await waitFor(() => {
      expect(screen.getByText(/รันบอร์ดทดลองการทำงาน/i)).toBeInTheDocument();
    });

    expect(screen.getByText('Step 1: Run OCR')).toBeInTheDocument();
    expect(screen.getByText('Step 2: AI Extract')).toBeInTheDocument();
    expect(screen.getByText('Step 3: RAG Prep')).toBeInTheDocument();
  });

  it('requires project and file for OCR', async () => {
    const user = userEvent.setup();
    render(<SandboxTestArea promptType="ocr_extraction" />);
    
    await waitFor(() => {
      expect(screen.getByRole('button', { name: /เริ่มรัน OCR/i })).toBeDisabled();
    });

    // Upload file
    const file = new File(['dummy content'], 'test.pdf', { type: 'application/pdf' });
    const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
    await userEvent.upload(fileInput, file);

    // After uploading file, button is enabled, but submitting will fail without project in AI Extract step.
    expect(screen.getByRole('button', { name: /เริ่มรัน OCR/i })).not.toBeDisabled();
  });

  it('runs OCR and polls status', async () => {
    const user = userEvent.setup();
    
    mockSubmitSandboxOcr.mockResolvedValue({ requestPublicId: 'req-1' });
    mockGetSandboxJobStatus.mockResolvedValue({ status: 'completed', ocrText: 'Extracted text from PDF' });

    render(<SandboxTestArea promptType="ocr_extraction" />);

    // Upload file
    const file = new File(['dummy content'], 'test.pdf', { type: 'application/pdf' });
    const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
    await userEvent.upload(fileInput, file);

    const runBtn = screen.getByRole('button', { name: /เริ่มรัน OCR/i });
    await user.click(runBtn);

    expect(mockSubmitSandboxOcr).toHaveBeenCalled();

    await waitFor(() => {
      expect(mockGetSandboxJobStatus).toHaveBeenCalledWith('req-1');
    }, { timeout: 3000 }); // Polling interval is 2s
  });
});
