import { describe, it, expect } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import { MemoryRouter, Route, Routes, useLocation } from 'react-router-dom';
import { useUrlState, pageOf } from './useUrlState';
import BackButton from '../components/ui/BackButton';

/**
 * قرارداد: وضعیت لیست در URL است، پس «بازگشت» (که همان URL قبلی را برمی‌گرداند)
 * فیلتر و صفحه را هم برمی‌گرداند.
 */
function ListPage() {
  const [state, setState] = useUrlState({ page: '1', search: '', status: '' });
  const location = useLocation();

  return (
    <div>
      <span data-testid="qs">{location.search}</span>
      <span data-testid="state">{`${state.page}|${state.search}|${state.status}`}</span>
      <button onClick={() => setState({ search: 'مریم', page: '1' })}>جستجو</button>
      <button onClick={() => setState({ status: 'paid', page: '1' })}>فیلتر</button>
      <button onClick={() => setState({ page: '3' })}>صفحه ۳</button>
      <button onClick={() => { setState({ status: 'paid' }); setState({ page: '2' }); }}>دو تغییر پشت‌سرهم</button>
      <a href="/detail" onClick={(e) => { e.preventDefault(); window.history.pushState({}, '', '/detail'); }}>x</a>
    </div>
  );
}

function DetailPage() {
  return (
    <>
      <span>جزئیات</span>
      <BackButton fallback="/list" />
    </>
  );
}

function renderApp(entries: string[] = ['/list']) {
  return render(
    <MemoryRouter initialEntries={entries}>
      <Routes>
        <Route path="/list" element={<ListPage />} />
        <Route path="/detail" element={<DetailPage />} />
      </Routes>
    </MemoryRouter>,
  );
}

describe('useUrlState', () => {
  it('مقدار اولیه را از URL می‌خواند', () => {
    renderApp(['/list?page=2&search=علی&status=paid']);
    expect(screen.getByTestId('state')).toHaveTextContent('2|علی|paid');
  });

  it('تغییر فیلتر در query string می‌نشیند و صفحه را یک می‌کند', () => {
    renderApp(['/list?page=4']);
    fireEvent.click(screen.getByText('فیلتر'));

    expect(screen.getByTestId('qs').textContent).toContain('status=paid');
    expect(screen.getByTestId('state')).toHaveTextContent('1|');
  });

  it('مقدارِ برابرِ پیش‌فرض از URL حذف می‌شود', () => {
    renderApp(['/list?page=3']);
    fireEvent.click(screen.getByText('صفحه ۳'));
    expect(screen.getByTestId('qs').textContent).toContain('page=3');

    fireEvent.click(screen.getByText('فیلتر'));   // page → '1' = پیش‌فرض
    expect(screen.getByTestId('qs').textContent).not.toContain('page=');
  });

  it('دو تغییرِ پشت‌سرهم در یک handler همدیگر را پاک نمی‌کنند', () => {
    renderApp(['/list']);
    fireEvent.click(screen.getByText('دو تغییر پشت‌سرهم'));

    // مودالِ فیلتر دقیقاً همین کار را می‌کند: setFilters(...) و بعد setPage(1).
    expect(screen.getByTestId('state')).toHaveTextContent('2||paid');
  });

  it('بازگشت از صفحهٔ جزئیات، فیلتر و صفحهٔ لیست را دست‌نخورده برمی‌گرداند', () => {
    render(
      <MemoryRouter initialEntries={['/list?page=3&search=مریم&status=paid', '/detail']} initialIndex={1}>
        <Routes>
          <Route path="/list" element={<ListPage />} />
          <Route path="/detail" element={<DetailPage />} />
        </Routes>
      </MemoryRouter>,
    );

    expect(screen.getByText('جزئیات')).toBeInTheDocument();
    fireEvent.click(screen.getByRole('button', { name: /بازگشت/ }));

    expect(screen.getByTestId('state')).toHaveTextContent('3|مریم|paid');
  });

  it('pageOf مقدار نامعتبر را به ۱ می‌برد', () => {
    expect(pageOf('')).toBe(1);
    expect(pageOf('0')).toBe(1);
    expect(pageOf('abc')).toBe(1);
    expect(pageOf('7')).toBe(7);
  });
});
