import { jsx } from "react/jsx-runtime";
import React from "react";
import { fireEvent, render, screen } from "@testing-library/react";
import { format } from "date-fns";
import { ThemeProvider, Datepicker, v3theme } from "../..";
import { toUTC } from "./Datepicker";
describe("<Datepicker />", () => {
  const testDate = new Date(2022, 7, 3, 14, 0, 0);
  let originalDateTimeFormat;
  beforeAll(() => {
    originalDateTimeFormat = Intl.DateTimeFormat;
  });
  describe("Snapshots", () => {
    it("should match snapshot when v3Theme is settled", () => {
      const { container } = render(
        /* @__PURE__ */ jsx(ThemeProvider, { theme: v3theme, children: /* @__PURE__ */ jsx(Datepicker, { type: "single" }) })
      );
      expect(container).toMatchSnapshot();
    });
    it("should match with single Datepicker", () => {
      const { container } = render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single" }) })
      );
      expect(container).toMatchSnapshot();
    });
    it("should match with range Datepicker", () => {
      const { container } = render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "range" }) })
      );
      expect(container).toMatchSnapshot();
    });
    it("should match with default selected date single Datepicker", () => {
      jest.useFakeTimers("modern").setSystemTime(testDate);
      const { container } = render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single", startDate: testDate }) })
      );
      expect(container).toMatchSnapshot();
    });
    it("should match with default selected dates range Datepicker", () => {
      jest.useFakeTimers("modern").setSystemTime(testDate);
      const endDate = /* @__PURE__ */ new Date();
      endDate.setDate(testDate.getDate() + 15);
      const { container } = render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "range", startDate: testDate, endDate }) })
      );
      expect(container).toMatchSnapshot();
    });
    it("should match with custom placeholder single Datepicker", () => {
      const { container } = render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(
          Datepicker,
          {
            type: "single",
            placeholder: "This is a custom placeholder :)"
          }
        ) })
      );
      expect(container).toMatchSnapshot();
    });
    it("should match with disabled past dates Datepicker", () => {
      const { container } = render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single", disablePastDates: true }) })
      );
      expect(container).toMatchSnapshot();
    });
    it("should match with disabled future dates Datepicker", () => {
      const { container } = render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single", disableFutureDates: true }) })
      );
      expect(container).toMatchSnapshot();
    });
    it("should match with disabled Datepicker", () => {
      const { container } = render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single", disabled: true }) })
      );
      expect(container).toMatchSnapshot();
    });
    it("should match with error Datepicker", () => {
      const { container } = render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single", error: "This is an error" }) })
      );
      expect(container).toMatchSnapshot();
    });
  });
  describe("Unit", () => {
    const dateFormat = "MMM d, yyyy";
    it("should call onSelectSingle function on single Datepicker", () => {
      const onSelectSingle = jest.fn();
      render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single", onSelectSingle }) })
      );
      expect(onSelectSingle).not.toHaveBeenCalled();
      fireEvent.click(screen.getByRole("button"));
      const day10 = screen.queryAllByText("10")[0];
      fireEvent.click(day10);
      expect(onSelectSingle).toHaveBeenCalledTimes(1);
    });
    it("should call onSelectRange function on range Datepicker", () => {
      const onSelectRange = jest.fn();
      render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "range", onSelectRange }) })
      );
      expect(onSelectRange).not.toHaveBeenCalled();
      fireEvent.click(screen.getByRole("button"));
      const day10 = screen.queryAllByText("10")[0];
      const day20 = screen.queryAllByText("20")[0];
      fireEvent.click(day10);
      expect(onSelectRange).toHaveBeenCalledTimes(1);
      fireEvent.click(day20);
      expect(onSelectRange).toHaveBeenCalledTimes(2);
    });
    it("should call onCustomSelectRange function on range Datepicker", () => {
      const onCustomSelectRange = jest.fn();
      render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "range", onSelectRange: onCustomSelectRange }) })
      );
      expect(onCustomSelectRange).not.toHaveBeenCalled();
      fireEvent.click(screen.getByRole("button"));
      const day10 = screen.queryAllByText("10")[0];
      const day20 = screen.queryAllByText("20")[0];
      fireEvent.click(day10);
      expect(onCustomSelectRange).toHaveBeenCalledTimes(1);
      fireEvent.click(day20);
      expect(onCustomSelectRange).toHaveBeenCalledTimes(2);
    });
    it("should display default date on single Datepicker", () => {
      const currentDate = /* @__PURE__ */ new Date();
      render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single", startDate: currentDate }) })
      );
      const formattedDate = format(toUTC(currentDate), dateFormat);
      expect(screen.getByText(formattedDate)).toBeVisible();
    });
    it("should display default date range on range Datepicker", () => {
      const currentDate = /* @__PURE__ */ new Date();
      const end = /* @__PURE__ */ new Date();
      end.setDate(currentDate.getDate() + 15);
      const formattedStartDate = format(toUTC(currentDate), dateFormat);
      const formattedEndDate = format(toUTC(end), dateFormat);
      render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "range", startDate: currentDate, endDate: end }) })
      );
      expect(
        screen.getByText(`${formattedStartDate} - ${formattedEndDate}`)
      ).toBeVisible();
    });
    it('should display custom placeholder and "Select Date" if none is provided', () => {
      const { rerender } = render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(
          Datepicker,
          {
            type: "single",
            placeholder: "This is a custom placeholder :)"
          }
        ) })
      );
      expect(screen.getByText("This is a custom placeholder :)")).toBeVisible();
      rerender(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single" }) })
      );
      expect(screen.getByText("Select Date")).toBeVisible();
    });
    it("should disable past dates", () => {
      render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single", disablePastDates: true }) })
      );
      fireEvent.click(screen.getByRole("button"));
      const previousMonthArrow = screen.getByTestId("previous-month-arrow");
      fireEvent.click(previousMonthArrow);
      [...Array(25)].forEach(
        (_e, i) => expect(
          screen.getAllByText(`${i + 1}`)[0].closest("div")
        ).toHaveAttribute("disabled")
      );
    });
    it("should disable future dates", () => {
      render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single", startDate: testDate, disableFutureDates: true }) })
      );
      fireEvent.click(screen.getByRole("button"));
      const nextMonthArrow = screen.getByTestId("next-month-arrow");
      fireEvent.click(nextMonthArrow);
      [...Array(25)].forEach(
        (_e, i) => expect(
          screen.getAllByText(`${i + 1}`)[0].closest("div")
        ).toHaveAttribute("disabled")
      );
    });
    it("should disable past dates from specific date", () => {
      jest.useFakeTimers("modern").setSystemTime(testDate);
      const date = /* @__PURE__ */ new Date();
      date.setDate(testDate.getDate() + 15);
      render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single", disablePastFrom: date }) })
      );
      fireEvent.click(screen.getByRole("button"));
      for (let i = 1; i <= 17; i++) {
        expect(screen.getAllByText(`${i}`)[0].closest("div")).toHaveAttribute(
          "disabled"
        );
      }
    });
    it("should disable future dates from specific date", () => {
      jest.useFakeTimers("modern").setSystemTime(testDate);
      const date = /* @__PURE__ */ new Date();
      date.setDate(testDate.getDate() + 15);
      render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single", disableFutureFrom: date }) })
      );
      fireEvent.click(screen.getByRole("button"));
      for (let i = 19; i <= 31; i++) {
        expect(screen.getAllByText(`${i}`)[0].closest("div")).toHaveAttribute(
          "disabled"
        );
      }
    });
    it("should be disabled", () => {
      render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single", startDate: testDate, disabled: true }) })
      );
      const formattedDate = format(toUTC(testDate), dateFormat);
      const datepickerInput = screen.getByText(formattedDate);
      expect(datepickerInput).toHaveAttribute("disabled");
      expect(datepickerInput.closest("div")).toHaveAttribute("disabled");
    });
    it("should display an error", () => {
      render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single", error: "This is an error" }) })
      );
      expect(screen.getByText("This is an error")).toBeVisible();
    });
  });
  describe("Internationalization", () => {
    let originalNavigator;
    beforeEach(() => {
      originalNavigator = global.navigator;
    });
    afterEach(() => {
      global.Intl.DateTimeFormat = originalDateTimeFormat;
      Object.defineProperty(global, "navigator", {
        value: originalNavigator,
        writable: true
      });
    });
    it("should display calendar in English when locale is not supported", () => {
      render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single", locale: "xx-XX" }) })
      );
      fireEvent.click(screen.getByRole("button"));
      const currentDate = /* @__PURE__ */ new Date();
      const currentMonth = new Intl.DateTimeFormat("en-US", {
        month: "long"
      }).format(currentDate);
      expect(
        screen.getByText(new RegExp(currentMonth, "i"))
      ).toBeInTheDocument();
    });
    it("should display calendar in Portuguese when browser locale is pt-BR", () => {
      render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single", locale: "pt-BR" }) })
      );
      fireEvent.click(screen.getByRole("button"));
      const currentDate = /* @__PURE__ */ new Date();
      const months = [
        "janeiro",
        "fevereiro",
        "mar\xE7o",
        "abril",
        "maio",
        "junho",
        "julho",
        "agosto",
        "setembro",
        "outubro",
        "novembro",
        "dezembro"
      ];
      const currentMonth = months[currentDate.getMonth()];
      expect(
        screen.getByText(new RegExp(currentMonth, "i"))
      ).toBeInTheDocument();
    });
    it("should display only the first letter of each weekday in uppercase", () => {
      render(
        /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(Datepicker, { type: "single" }) })
      );
      fireEvent.click(screen.getByRole("button"));
      const weekdayLetters = ["S", "M", "T", "W", "T", "F", "S"];
      weekdayLetters.forEach((letter) => {
        expect(screen.getAllByText(letter).length).toBeGreaterThan(0);
      });
      expect(screen.queryByText("sun")).not.toBeInTheDocument();
      expect(screen.queryByText("mon")).not.toBeInTheDocument();
    });
  });
});
