import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { ThemeProvider } from '../../theme';

jest.mock('next-intl', () => ({
  useTranslations: () => (key: string) => key,
  useLocale: () => 'en',
}));

const PROVINCES = [
  { id: 1, nameFa: 'تهران', nameEn: 'Tehran', sortOrder: 0 },
  { id: 4, nameFa: 'فارس', nameEn: 'Fars', sortOrder: 3 },
];
const CITIES = [{ id: 101, provinceId: 1, nameFa: 'تهران', nameEn: 'Tehran', sortOrder: 0 }];
const DISTRICTS = [{ id: 1001, cityId: 101, nameFa: 'منطقه ۱', nameEn: 'District 1', sortOrder: 0 }];

// Mock the aggressively-cached geography hooks so the cascade renders deterministically:
// city 101 has districts; any other city is whole-city-only (fetched-but-empty).
jest.mock('@/services/geography', () => ({
  useProvinces: () => ({ data: PROVINCES, isLoading: false, isSuccess: true }),
  useCities: (provinceId: number | null) => ({ data: provinceId ? CITIES : [], isLoading: false, isSuccess: provinceId != null }),
  useDistricts: (cityId: number | null) => ({
    data: cityId === 101 ? DISTRICTS : [],
    isLoading: false,
    isSuccess: cityId != null,
  }),
}));

import CascadingRegionSelect, { type CascadingRegionValue } from './CascadingRegionSelect';

const NONE: CascadingRegionValue = { provinceId: null, cityId: null, districtId: null };

function renderSelect(value: CascadingRegionValue) {
  const onChange = jest.fn();
  const utils = render(
    <ThemeProvider>
      <CascadingRegionSelect value={value} onChange={onChange} />
    </ThemeProvider>,
  );
  return { ...utils, onChange };
}

describe('<CascadingRegionSelect/> component', () => {
  it('lists provinces and blocks the city level until a province is chosen', () => {
    renderSelect(NONE);
    expect(screen.getByRole('combobox', { name: 'province' })).toBeInTheDocument();
    // City is not selectable yet — its helper prompts to pick a province first.
    expect(screen.getByText('city_needs_province')).toBeInTheDocument();
  });

  it('resets the city/district when the province changes', async () => {
    const user = userEvent.setup();
    const { onChange } = renderSelect({ provinceId: 1, cityId: 101, districtId: 1001 });
    await user.click(screen.getByRole('combobox', { name: 'province' }));
    await user.click(screen.getByRole('option', { name: 'Fars' }));
    expect(onChange).toHaveBeenCalledWith({ provinceId: 4, cityId: null, districtId: null });
  });

  it('offers the whole-city option plus districts for a city that has them', async () => {
    const user = userEvent.setup();
    const { onChange } = renderSelect({ provinceId: 1, cityId: 101, districtId: null });
    await user.click(screen.getByRole('combobox', { name: 'district' }));
    expect(screen.getByRole('option', { name: 'whole_city' })).toBeInTheDocument();
    await user.click(screen.getByRole('option', { name: 'District 1' }));
    expect(onChange).toHaveBeenCalledWith({ provinceId: 1, cityId: 101, districtId: 1001 });
  });

  it('surfaces the whole-city affordance for a city with no districts', () => {
    renderSelect({ provinceId: 1, cityId: 201, districtId: null });
    expect(screen.getByText('no_districts')).toBeInTheDocument();
  });
});
