/**
 * @file ServicesQA.test.tsx
 * Full stable test suite for ServicesQA component
 */

import { render, screen, fireEvent, act } from "@testing-library/react";
import "@testing-library/jest-dom";
import ServicesQA from "@/apps/new-ui/components/AppointmentComponents/ServicesQA";

// ---------- MOCKS ----------

// Swiper mock
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: {} }));

// useGetUserInfo mock
jest.mock("@/apps/new-ui/services/User", () => ({
  useGetUserInfo: () => ({
    data: {
      current_user: {
        services: [
          { name: "ماساژ", emoji: "💆", price: 200 },
          { name: "مانیکور", emoji: "💅", price: 150 },
          { name: "اصلاح", emoji: "✂️", price: 120 },
        ],
      },
    },
  }),
}));

// react-router
jest.mock("react-router-dom", () => ({
  ...jest.requireActual("react-router-dom"),
  useLocation: () => ({ pathname: "/dashboard" }),
}));

// AddService mock
jest.mock("@/apps/new-ui/pages/AddService/AddService", () => {
  return function MockAddService({ onclick }: any) {
    return (
      <div data-testid="add-service">
        <button data-testid="close-add-service" onClick={onclick}>
          close
        </button>
      </div>
    );
  };
});

// localStorage mock
beforeEach(() => {
  Storage.prototype.getItem = jest.fn(() => null);
  Storage.prototype.setItem = jest.fn();
  Storage.prototype.removeItem = jest.fn();
});

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

// ------------------------------------------------------
//                       TESTS
// ------------------------------------------------------

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

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

test("selects a service and persists serviceTitle + price", async () => {
  const onChange = jest.fn();

  render(<ServicesQA onChange={onChange} />);

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

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

  expect(localStorage.setItem).toHaveBeenCalledWith("serviceTitle", "مانیکور");
  expect(localStorage.setItem).toHaveBeenCalledWith("servicePrice", "150");
  expect(onChange).toHaveBeenCalledWith("مانیکور");
});

test("opens AddService modal when no services available", async () => {
  jest.mocked(Storage.prototype.getItem).mockReturnValue(null);

  render(<ServicesQA serviceList={[]} />);

  const addBtn = screen.getByText("افزودن خدمات");

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

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

test("closing AddService modal via overlay click", async () => {
  render(<ServicesQA serviceList={[]} />);

  await act(async () => {
    fireEvent.click(screen.getByText("افزودن خدمات"));
  });

  // modal should exist
  expect(screen.getByTestId("add-service")).toBeInTheDocument();

  // click backdrop
  const backdrop = document.querySelector(".fixed");

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

test("closing AddService modal via X button inside mock AddService", async () => {
  render(<ServicesQA serviceList={[]} />);

  await act(async () => {
    fireEvent.click(screen.getByText("افزودن خدمات"));
  });

  expect(screen.getByTestId("add-service")).toBeInTheDocument();

  await act(async () => {
    fireEvent.click(screen.getByTestId("close-add-service"));
  });

  expect(screen.queryByTestId("add-service")).toBeNull();
});
