import { render, screen, fireEvent } from "@testing-library/react";

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

// Router mock
jest.mock("react-router-dom", () => ({
  Link: ({ children, ...rest }: any) => <a {...rest}>{children}</a>,
}));

// BeatLoader mock
jest.mock("react-spinners", () => ({
  BeatLoader: () => <div data-testid="loader" />,
}));

// GuidedOverlay mock
jest.mock("@/apps/new-ui/components/GuidedOverlay/GuidedOverlay", () => () => (
  <div data-testid="guided-overlay" />
));

// Calendar mock
jest.mock(
  "@/apps/new-ui/pages/AdvancedTurn/+components/Calendar/MobileCalendarSingleMonth.tsx",
  () =>
    ({ onSelect }: any) => (
      <div>
        <button
          data-testid="calendar-btn"
          onClick={() => onSelect("2024-01-02")}
        >
          select-date
        </button>
      </div>
    ),
);

// WorkHour mock
jest.mock(
  "@/apps/new-ui/pages/CreateTimeTable/+components/WorkHour.tsx",
  () => (props: any) => (
    <div data-testid="workhour" data-props={JSON.stringify(props)} />
  ),
);

// Toggle mock
jest.mock(
  "@/apps/new-ui/pages/CreateTimeTable/+components/DraggableToggleButton.tsx",
  () => (props: any) => (
    <button data-testid="toggle" onClick={() => props.setCustomerTime(true)}>
      toggle-holiday
    </button>
  ),
);

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

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

import { useGetUserInfo } from "@/apps/new-ui/services/User";
import { useGetMonthScheduleForPublic } from "@/apps/new-ui/services/NewTest";
import HolidayManagement from "@/apps/new-ui/pages/CreateTimeTable/+components/HolidayManagement";

// --------------------------------------------------------------------
// UTIL: prepare mock API data
// --------------------------------------------------------------------
const mockUserInfoWithService = {
  current_user: {
    services: [{ id: 1, title: "سرویس تست" }],
  },
};

const mockUserInfoNoService = {
  current_user: {
    services: [],
  },
};

const mockMonthData = {
  days: [],
  holidays: [],
  iran_holidays: [],
  year: 1403,
  month: 10,
};

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

describe("HolidayManagement Component", () => {
  beforeEach(() => {
    localStorage.clear();
    jest.clearAllMocks();
  });

  test("renders Lottie section when user has no services", () => {
    (useGetUserInfo as jest.Mock).mockReturnValue({
      data: mockUserInfoNoService,
    });

    (useGetMonthScheduleForPublic as jest.Mock).mockReturnValue({
      data: mockMonthData,
      refetch: jest.fn(),
    });

    render(<HolidayManagement />);

    expect(screen.getByTestId("loader")).toBeInTheDocument();
    expect(screen.getByText("ثبت خدمات جدید")).toBeInTheDocument();
  });

  test("renders calendar and WorkHour when user HAS services", () => {
    (useGetUserInfo as jest.Mock).mockReturnValue({
      data: mockUserInfoWithService,
    });

    (useGetMonthScheduleForPublic as jest.Mock).mockReturnValue({
      data: mockMonthData,
      refetch: jest.fn(),
    });

    render(<HolidayManagement />);

    expect(screen.getByTestId("calendar-btn")).toBeInTheDocument();
    expect(screen.getByTestId("workhour")).toBeInTheDocument();
  });

  test("date select updates selected day (handleDateSelect)", () => {
    // 1. جلوگیری از override شدن مقدار توسط HolidayManagement
    localStorage.setItem("appointmentDateGregorian", "2024-01-02");

    (useGetUserInfo as jest.Mock).mockReturnValue({
      data: mockUserInfoWithService,
    });

    (useGetMonthScheduleForPublic as jest.Mock).mockReturnValue({
      data: mockMonthData,
      refetch: jest.fn(),
    });

    render(<HolidayManagement />);

    // 2. شبیه‌سازی انتخاب تاریخ
    fireEvent.click(screen.getByTestId("calendar-btn"));

    // 3. بررسی مقدار ذخیره شده
    const isoSaved = localStorage.getItem("appointmentDateGregorian");
    expect(isoSaved).toContain("2024-01-02");
  });

  test("toggle holiday works", () => {
    (useGetUserInfo as jest.Mock).mockReturnValue({
      data: mockUserInfoWithService,
    });

    (useGetMonthScheduleForPublic as jest.Mock).mockReturnValue({
      data: mockMonthData,
      refetch: jest.fn(),
    });

    render(<HolidayManagement />);

    const toggle = screen.getByTestId("toggle");
    fireEvent.click(toggle);

    expect(toggle).toBeInTheDocument(); // simply ensures it triggered
  });

  test("WorkHour receives selected multiple dates", () => {
    localStorage.setItem(
      "appointmentDateGregorianMulti",
      JSON.stringify(["1403/10/05"]),
    );

    (useGetUserInfo as jest.Mock).mockReturnValue({
      data: mockUserInfoWithService,
    });

    (useGetMonthScheduleForPublic as jest.Mock).mockReturnValue({
      data: mockMonthData,
      refetch: jest.fn(),
    });

    render(<HolidayManagement />);

    const wh = screen.getByTestId("workhour");
    const props = JSON.parse(wh.getAttribute("data-props") || "{}");

    expect(props.days).toEqual(["1403/10/05"]);
  });
});
