import { describe, it, expect, beforeEach, vi } from 'vitest';
import { screen, fireEvent, waitFor } from '@testing-library/react';
import { renderWithProviders } from '../test/utils';

vi.mock('../lib/api', () => ({
  api: { get: vi.fn(), post: vi.fn(), patch: vi.fn(), put: vi.fn(), delete: vi.fn() },
  ApiError: class extends Error {},
}));

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

import { api } from '../lib/api';
import PolicyFormPage from './PolicyFormPage';

const get = api.get as ReturnType<typeof vi.fn>;

/**
 * فیلدِ ساختگی: در هیچ کجای فرانت نوشته نشده. اگر در صفحه ظاهر شود، یعنی فرم واقعاً
 * از schema ساخته می‌شود و فیلد تازهٔ بک‌اند بدون تغییر فرانت کار می‌کند.
 */
const schema = {
  timing: {
    label: 'مدت نوبت',
    fields: ['made_up_field', 'patient_tags'],
    operators: ['equals', 'not_equals', 'greater_than', 'less_than', 'in', 'contains'],
    field_meta: [
      {
        key: 'made_up_field',
        label: 'فیلد ساختگی آزمون',
        type: 'int',
        operators: ['equals', 'greater_than'],
      },
      { key: 'patient_tags', label: 'برچسب‌های بیمار', type: 'list', operators: ['contains'] },
    ],
    effects: [
      { type: 'min_duration_minutes', label: 'حداقل مدت (دقیقه)', value_type: 'int', combination: 'max' },
    ],
  },
};

function mockApi() {
  get.mockImplementation((path: string) => {
    if (path === '/api/v1/policy-schema') return Promise.resolve({ success: true, data: schema });
    if (path === '/api/v1/policy-templates') return Promise.resolve({ success: true, data: [] });
    return Promise.resolve({ success: true, data: null });
  });
}

async function openAdvanced() {
  renderWithProviders(<PolicyFormPage />, { route: '/admin/policies/new' });
  fireEvent.click(screen.getByText('پیشرفته'));
  await waitFor(() => expect(screen.getByText('افزودن شرط')).toBeInTheDocument());
  fireEvent.click(screen.getByText('افزودن شرط'));
}

describe('PolicyFormPage', () => {
  beforeEach(() => {
    vi.clearAllMocks();
    mockApi();
  });

  it('renders a field that exists only in the schema, with no frontend change', async () => {
    await openAdvanced();

    await waitFor(() => expect(screen.getByText('فیلد ساختگی آزمون')).toBeInTheDocument());
  });

  it('offers only the operators that make sense for the field type', async () => {
    await openAdvanced();

    await waitFor(() => expect(screen.getByText('برابر است با')).toBeInTheDocument());

    // فیلد از نوع `int` است، پس «شامل» — که فقط برای فهرست معنا دارد — نباید باشد.
    expect(screen.queryByText('شامل')).not.toBeInTheDocument();
  });

  it('renders the effects of the selected category from the schema', async () => {
    renderWithProviders(<PolicyFormPage />, { route: '/admin/policies/new' });
    fireEvent.click(screen.getByText('پیشرفته'));

    await waitFor(() => expect(screen.getByText('حداقل مدت (دقیقه)')).toBeInTheDocument());
    expect(screen.getByText(/ترکیب: max/)).toBeInTheDocument();
  });
});
