import { render, screen, fireEvent, act } from "@testing-library/react";
import { useGetUserInfo } from "@/apps/new-ui/services/User";
import Services from "@/apps/new-ui/components/AppointmentComponents/Services";

// ---- MOCKS ----

// mock Swiper to avoid DOM errors
jest.mock("swiper/react", () => ({
  Swiper: ({ children }: any) => <div data-testid="swiper">{children}</div>,
  SwiperSlide: ({ children }: any) => <div data-testid="slide">{children}</div>,
}));

jest.mock("swiper/modules", () => ({
  Navigation: {},
  Autoplay: {},
}));

// mock VoiceSearchInput
jest.mock("@/apps/new-ui/components/VoiceSearchInput", () => {
  return function MockVoiceInput(props: any) {
    return (
      <input
        data-testid="voice-input"
        value={props.value}
        placeholder={props.placeholder}
        onChange={(e) => props.onChange(e.target.value)}
      />
    );
  };
});


// mock AddService modal
jest.mock("@/apps/new-ui/pages/AddService/AddService", () => () => (
  <div data-testid="add-service">AddService Component</div>
));

// mock useGetUserInfo
jest.mock("@/apps/new-ui/services/User", () => ({
  useGetUserInfo: jest.fn(),
}));

// Helper localStorage mock
const localStore: Record<string, string> = {};
beforeEach(() => {
  localStorage.clear();
  Object.keys(localStore).forEach((k) => delete localStore[k]);

  jest.spyOn(window.localStorage.__proto__, "getItem").mockImplementation(
    (...args: any[]) => {
      const key = args[0];
      return localStore[key] || null;
    }
  );

  jest.spyOn(window.localStorage.__proto__, "setItem").mockImplementation(
    (...args: any[]) => {
      const [key, value] = args;
      localStore[key] = value;
    }
  );

  jest.spyOn(window.localStorage.__proto__, "removeItem").mockImplementation(
    (...args: any[]) => {
      const key = args[0];
      delete localStore[key];
    }
  );
});


// test data
const mockServices = [
  { emoji: "💆‍♀️", name: "ماساژ", price: 200 },
  { emoji: "💅", name: "مانیکور", price: 150 },
  { emoji: "💇‍♀️", name: "اصلاح", price: 100 },
];

describe("Services Component", () => {
  beforeEach(() => {
    (useGetUserInfo as jest.Mock).mockReturnValue({
      data: {
        current_user: {
          services: mockServices,
        },
      },
    });
  });

  test("renders services from API", () => {
    render(<Services />);

    expect(screen.getByTestId("swiper")).toBeInTheDocument();
    expect(screen.getAllByTestId("slide").length).toBe(3);

    expect(screen.getByText("ماساژ")).toBeInTheDocument();
    expect(screen.getByText("مانیکور")).toBeInTheDocument();
  });

  test("filters services when search input changes", () => {
    render(<Services />);

    const input = screen.getByTestId("voice-input");
   fireEvent.change(input, { target: { value: "اص" } });

expect(screen.getByText("اصلاح")).toBeInTheDocument();
expect(screen.queryByText("مانیکور")).toBeNull();
expect(screen.queryByText("ماساژ")).toBeNull();

  });
beforeEach(() => {
  localStorage.clear();
  jest.spyOn(localStorage.__proto__, "setItem");
});

afterEach(() => {
  jest.restoreAllMocks();
});

test("selecting a service updates localStorage and dispatches event", async () => {
  const eventSpy = jest.fn();
  window.addEventListener("serviceSelected", eventSpy);

  render(<Services />);

  await act(async () => {
    await new Promise((r) => setTimeout(r, 0));
  });

  eventSpy.mockClear();

  const manicureItem = screen.getByText("مانیکور");

  await act(async () => {
    fireEvent.click(manicureItem);
  });

  expect(eventSpy).toHaveBeenCalled();
  expect(localStorage.setItem).toHaveBeenCalledWith("serviceTitle", "مانیکور");
});


  test("opens AddService modal when add button clicked", () => {
    const dispatchSpy = jest.fn();

    render(<Services dispatchEvent={dispatchSpy} />);

    const addButton = screen.getByAltText("add service");
    expect(addButton).toBeInTheDocument();

    act(() => {
      fireEvent.click(addButton);
    });

    expect(dispatchSpy).toHaveBeenCalledWith("OPEN");
    expect(screen.getByTestId("add-service")).toBeInTheDocument();
  });
});
