import { describe, it, expect, beforeEach, vi } from 'vitest';
import { screen, 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 { Routes, Route } from 'react-router-dom';
import { api } from '../lib/api';
import PolicySimulationPage from './PolicySimulationPage';

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

const policy = {
  uuid: 'p1',
  category: 'pricing',
  name: 'تخفیف وفاداری',
  condition: {},
  effects: [{ type: 'discount_percent', value: 25 }],
  priority: 0,
  version: 2,
  active: false,
  valid_from: null,
  valid_to: null,
  address_uuid: null,
  service_uuid: null,
  catalog_category_uuid: null,
  specificity: 0,
};

function run(version: number, severity: string) {
  return {
    uuid: 'r1',
    policy_uuid: 'p1',
    policy_version: version,
    sample_size: 4,
    affected_count: 3,
    affected_percent: 75,
    severity,
    created_at: 1_700_000_000,
    warning: null,
    rows: [
      {
        appointment_uuid: 'a1',
        patient_name: 'ز. احمدی',
        slot_start: 1_700_000_000,
        before: '2,000,000 ریال',
        after: '1,500,000 ریال',
        reason: '500,000 ریال تخفیف',
      },
    ],
  };
}

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

function renderPage() {
  return renderWithProviders(
    <Routes>
      <Route path="/admin/policies/:policyUuid/simulate" element={<PolicySimulationPage />} />
    </Routes>,
    { route: '/admin/policies/p1/simulate' },
  );
}

describe('PolicySimulationPage', () => {
  beforeEach(() => vi.clearAllMocks());

  it('shows the before/after change of each affected appointment', async () => {
    mockApi([run(2, 'high')]);
    renderPage();

    await waitFor(() => expect(screen.getByText('ز. احمدی')).toBeInTheDocument());
    expect(screen.getByText('2,000,000 ریال')).toBeInTheDocument();
    expect(screen.getByText('1,500,000 ریال')).toBeInTheDocument();
    expect(screen.getByText(/تحت تأثیر: 3 نوبت/)).toBeInTheDocument();
  });

  /** گزارشِ نسخهٔ قبلی نباید دکمهٔ فعال‌سازی را باز کند — همان قاعدهٔ بک‌اند. */
  it('disables activation when the report belongs to an older version', async () => {
    mockApi([run(1, 'low')]);
    renderPage();

    await waitFor(() => expect(screen.getByText(/فعال‌سازی قانون/)).toBeDisabled());
    expect(screen.getByText(/دوباره آزمایش کنید/)).toBeInTheDocument();
  });

  it('enables activation when the report matches the current version', async () => {
    mockApi([run(2, 'low')]);
    renderPage();

    await waitFor(() => expect(screen.getByText(/فعال‌سازی قانون/)).toBeEnabled());
  });
});
