/* eslint-disable formatjs/no-literal-string-in-jsx */

import { User } from "@react-aria/test-utils"
import { userEvent } from "@testing-library/user-event"
import { FormProvider, useForm } from "react-hook-form"
import { afterEach, describe, expect, test } from "vitest"

import { Lang } from "@scandic-hotels/common/constants/language"
import { dt } from "@scandic-hotels/common/dt"
import { getLocalizedMonthName } from "@scandic-hotels/common/utils/dateFormatting"
import Date from "@scandic-hotels/design-system/Form/Date"

import { cleanup, render, screen } from "@/tests/utils"

const testUtilUser = new User({ interactionType: "touch" })

interface FormWrapperProps {
  defaultValues: Record<string, unknown>
  children: React.ReactNode
  onSubmit: (event: unknown) => void
}

function FormWrapper({ defaultValues, children, onSubmit }: FormWrapperProps) {
  const methods = useForm({
    defaultValues,
  })
  return (
    <FormProvider {...methods}>
      <form onSubmit={methods.handleSubmit(onSubmit)}>
        {children}
        <button type="submit">Submit</button>
      </form>
    </FormProvider>
  )
}

function selectOption(name: string, value: string) {
  const selectTester = testUtilUser.createTester("Select", {
    root: screen.getByTestId(name),
    interactionType: "touch",
  })

  selectTester.selectOption({ option: value })
}

const testCases = [
  {
    description: "date is set and submitted successfully",
    defaultValue: "",
    dateOfBirth: "1987-12-05",
    expectedOutput: {
      dateOfBirth: "1987-12-05",
      year: 1987,
      month: 12,
      day: 5,
    },
  },
  {
    description: "sets default value and submits successfully",
    defaultValue: "2000-01-01",
    dateOfBirth: "",
    expectedOutput: {
      dateOfBirth: "2000-01-01",
      year: 2000,
      month: 1,
      day: 1,
    },
  },
  {
    description: "accepts date exactly 18 years old",
    defaultValue: "",
    dateOfBirth: dt().subtract(18, "year").format("YYYY-MM-DD"),
    expectedOutput: {
      dateOfBirth: dt().subtract(18, "year").format("YYYY-MM-DD"),
    },
  },
  {
    description: "rejects date below 18 years old - by year",
    defaultValue: "",
    dateOfBirth: dt().subtract(17, "year").format("YYYY-MM-DD"),
    expectedOutput: {
      dateOfBirth: "",
    },
  },
  {
    description: "rejects date below 18 years old - by month",
    defaultValue: "",
    dateOfBirth: dt().subtract(18, "year").add(1, "month").format("YYYY-MM-DD"),
    expectedOutput: {
      dateOfBirth: "",
    },
  },
  {
    description: "rejects date below 18 years old - by day",
    defaultValue: "",
    dateOfBirth: dt().subtract(18, "year").add(1, "day").format("YYYY-MM-DD"),
    expectedOutput: {
      dateOfBirth: "",
    },
  },
]

describe.skip("Date input", () => {
  afterEach(cleanup)

  test.each(testCases)(
    "$description",
    async ({ defaultValue, dateOfBirth, expectedOutput }) => {
      const user = userEvent.setup()

      render(
        <FormWrapper
          defaultValues={{ dateOfBirth: defaultValue }}
          onSubmit={(data) => {
            expect(data).toEqual(expectedOutput)
          }}
        >
          <Date
            labels={{
              day: "day",
              month: "Month",
              year: "Year",
              errorMessage: "Date is required",
            }}
            lang={Lang.en}
            name="dateOfBirth"
          />
        </FormWrapper>
      )

      const date = dt(dateOfBirth).toDate()
      const year = date.getFullYear()
      const month = date.getMonth() + 1
      const day = date.getDate()

      selectOption("year", year.toString())
      selectOption("month", getLocalizedMonthName(month, Lang.en))
      selectOption("day", day.toString())

      const submitButton = screen.getByRole("button", { name: /submit/i })
      await user.click(submitButton)
    }
  )
})
