import { jsxs, jsx } from "react/jsx-runtime";
import { createRef, Fragment } from "react";
import { isMobile } from "is-mobile";
import assert from "assert";
import { Box } from "../Box/Box.mjs";
import { Column } from "../Column/Column.mjs";
import { Columns } from "../Columns/Columns.mjs";
import { Dropdown } from "../Dropdown/Dropdown.mjs";
import { Field } from "../private/Field/Field.mjs";
import { Secondary } from "../Secondary/Secondary.mjs";
import { Strong } from "../Strong/Strong.mjs";
import { Text, IconCritical, IconPositive, IconCaution } from "../Accordion/AccordionItem.mjs";
import { Stack } from "../Stack/Stack.mjs";
import { buildDataAttributes } from "../Accordion/Accordion.mjs";
import { nativeInput } from "./MonthPicker.css.mjs";
const FieldLabel = ({
  id,
  htmlFor,
  label,
  disabled,
  secondaryLabel,
  tertiaryLabel,
  description,
  descriptionId,
  data
}) => {
  if (!label && !description) {
    return null;
  }
  const labelEl = /* @__PURE__ */ jsxs(Text, { tone: disabled ? "secondary" : void 0, children: [
    /* @__PURE__ */ jsx(Strong, { children: label }),
    secondaryLabel ? /* @__PURE__ */ jsxs(Secondary, { children: [
      " (",
      secondaryLabel,
      ")"
    ] }) : null
  ] });
  return /* @__PURE__ */ jsxs(Stack, { space: "xsmall", data, children: [
    label ? /* @__PURE__ */ jsxs(Box, { component: "span", display: "flex", justifyContent: "spaceBetween", children: [
      htmlFor === false ? labelEl : /* @__PURE__ */ jsx("label", { id, htmlFor, children: labelEl }),
      tertiaryLabel ? /* @__PURE__ */ jsxs(Text, { children: [
        " ",
        tertiaryLabel
      ] }) : null
    ] }) : null,
    description ? /* @__PURE__ */ jsx(Box, { paddingTop: label ? "xxsmall" : void 0, paddingBottom: "xxsmall", children: /* @__PURE__ */ jsx(Text, { tone: "secondary", id: descriptionId, children: description }) }) : null
  ] });
};
const tones = ["neutral", "critical", "positive", "caution"];
const icon = {
  critical: /* @__PURE__ */ jsx(IconCritical, { tone: "critical" }),
  positive: /* @__PURE__ */ jsx(IconPositive, { tone: "positive" }),
  caution: /* @__PURE__ */ jsx(IconCaution, { tone: "caution" })
};
const FieldMessage = ({
  id,
  tone = "neutral",
  message,
  secondaryMessage,
  reserveMessageSpace = true,
  disabled,
  data,
  ...restProps
}) => {
  if (tones.indexOf(tone) === -1) {
    throw new Error(`Invalid tone: ${tone}`);
  }
  if (!message && !secondaryMessage && !reserveMessageSpace) {
    return null;
  }
  const showMessage = !disabled && message;
  return /* @__PURE__ */ jsxs(
    Box,
    {
      id,
      display: "flex",
      justifyContent: "flexEnd",
      ...buildDataAttributes({ data, validateRestProps: restProps }),
      children: [
        /* @__PURE__ */ jsx(Box, { flexGrow: 1, userSelect: showMessage ? void 0 : "none", children: /* @__PURE__ */ jsx(
          Text,
          {
            size: "small",
            tone: tone === "neutral" ? "secondary" : tone,
            icon: showMessage && tone !== "neutral" ? icon[tone] : void 0,
            children: showMessage ? message : " "
          }
        ) }),
        secondaryMessage && !disabled ? /* @__PURE__ */ jsx(Box, { paddingLeft: "xsmall", flexGrow: 0, children: secondaryMessage }) : null
      ]
    }
  );
};
const mergeIds = (...ids) => {
  const validIds = ids.filter(Boolean);
  if (validIds.length === 0) {
    return void 0;
  }
  return validIds.join(" ");
};
const FieldGroup = ({
  id,
  disabled,
  children,
  secondaryLabel,
  tertiaryLabel,
  description,
  message,
  reserveMessageSpace = false,
  tone,
  required,
  role,
  space = "xsmall",
  data,
  ...restProps
}) => {
  const labelId = `${id}-label`;
  const messageId = `${id}-message`;
  const descriptionId = description ? `${id}-description` : void 0;
  let ariaLabelledBy;
  let ariaLabel;
  if ("label" in restProps && restProps.label) {
    ariaLabelledBy = labelId;
  } else if ("aria-labelledby" in restProps && restProps["aria-labelledby"]) {
    ariaLabelledBy = restProps["aria-labelledby"];
  } else if ("aria-label" in restProps && restProps["aria-label"]) {
    ariaLabel = restProps["aria-label"];
  }
  return /* @__PURE__ */ jsx(
    Box,
    {
      component: "fieldset",
      disabled,
      id,
      role,
      "aria-labelledby": ariaLabelledBy,
      "aria-label": ariaLabel,
      "aria-required": required,
      ...buildDataAttributes({ data, validateRestProps: restProps }),
      children: /* @__PURE__ */ jsxs(Stack, { space, children: [
        "label" in restProps && restProps.label || description ? /* @__PURE__ */ jsx(Box, { component: "legend", id: labelId, children: /* @__PURE__ */ jsx(
          FieldLabel,
          {
            htmlFor: false,
            label: "label" in restProps ? restProps.label : void 0,
            secondaryLabel,
            tertiaryLabel,
            disabled,
            description,
            descriptionId
          }
        ) }) : null,
        children({
          disabled,
          "aria-describedby": mergeIds(
            message ? messageId : void 0,
            descriptionId
          )
        }),
        message || reserveMessageSpace ? /* @__PURE__ */ jsx(
          FieldMessage,
          {
            id: messageId,
            tone,
            disabled,
            message,
            reserveMessageSpace
          }
        ) : null
      ] })
    }
  );
};
const defaultMonthNames = [
  "Jan",
  "Feb",
  "Mar",
  "Apr",
  "May",
  "Jun",
  "Jul",
  "Aug",
  "Sep",
  "Oct",
  "Nov",
  "Dec"
];
const getMonths = (monthNames) => monthNames.map((monthName, i) => /* @__PURE__ */ jsx("option", { value: i + 1, children: monthName }, i));
const getYears = (min, max, ascending) => [...new Array(max - min + 1)].map((_v, i) => {
  const yearStr = String(ascending ? i + min : max - i);
  return /* @__PURE__ */ jsx("option", { value: yearStr, children: yearStr }, yearStr);
});
const currYear = (/* @__PURE__ */ new Date()).getFullYear();
const renderNativeInput = isMobile({ tablet: true });
const customValueToString = ({ month, year }) => month && year ? `${year}-${month < 10 ? "0" : ""}${month}` : void 0;
const stringToCustomValue = (value) => {
  const [year, month] = value.split("-");
  return {
    month: parseInt(month, 10),
    year: parseInt(year, 10)
  };
};
const makeChangeHandler = (onChange, value, fieldType) => (event) => {
  if (typeof onChange === "function") {
    onChange(
      {
        month: {
          year: value && value.year ? value.year : void 0,
          month: parseInt(event.target.value, 10) || void 0
        },
        year: {
          month: value && value.month ? value.month : void 0,
          year: parseInt(event.target.value, 10) || void 0
        },
        native: stringToCustomValue(event.target.value)
      }[fieldType]
    );
  }
};
const MonthPicker = ({
  id,
  value,
  onChange,
  onBlur,
  onFocus,
  tone,
  disabled,
  minYear = currYear - 100,
  maxYear = currYear,
  ascendingYears = false,
  monthLabel = "Month",
  yearLabel = "Year",
  monthNames = defaultMonthNames,
  ...restProps
}) => {
  assert(monthNames.length === 12, "monthNames array must contain 12 items");
  const currentValue = {
    month: value && value.month ? value.month : void 0,
    year: value && value.year ? value.year : void 0
  };
  const monthRef = createRef();
  const yearRef = createRef();
  const monthId = `${id}-month`;
  const yearId = `${id}-year`;
  const blurHandler = onBlur ? (event) => {
    const fireIfExternal = (element) => {
      if (element !== monthRef.current && element !== yearRef.current) {
        onBlur();
      }
    };
    if (event.relatedTarget !== null) {
      fireIfExternal(event.relatedTarget);
    } else {
      setTimeout(() => {
        fireIfExternal(document.activeElement);
      });
    }
  } : void 0;
  const focusHandler = onFocus ? (event) => {
    if (event.relatedTarget !== monthRef.current && event.relatedTarget !== yearRef.current) {
      onFocus();
    }
  } : void 0;
  const nativeField = /* @__PURE__ */ jsx(
    Field,
    {
      id,
      tone,
      disabled,
      value: customValueToString(currentValue),
      ...restProps,
      icon: void 0,
      prefix: void 0,
      name: void 0,
      autoComplete: void 0,
      secondaryMessage: null,
      children: (overlays, { className, ...fieldProps }) => /* @__PURE__ */ jsxs(Fragment, { children: [
        /* @__PURE__ */ jsx(
          Box,
          {
            component: "input",
            type: "month",
            value: customValueToString(currentValue),
            onChange: onChange && makeChangeHandler(onChange, value, "native"),
            onBlur,
            onFocus,
            ...fieldProps,
            height: "touchable",
            className: [className, nativeInput]
          }
        ),
        overlays
      ] })
    }
  );
  const customFieldGroup = /* @__PURE__ */ jsx(FieldGroup, { id, tone, disabled, ...restProps, children: (fieldGroupProps) => /* @__PURE__ */ jsxs(Columns, { space: "small", children: [
    /* @__PURE__ */ jsx(Column, { children: /* @__PURE__ */ jsx(
      Dropdown,
      {
        id: monthId,
        value: currentValue.month || "",
        onChange: makeChangeHandler(onChange, value, "month"),
        onBlur: blurHandler,
        onFocus: focusHandler,
        tone,
        placeholder: monthLabel,
        "aria-label": monthLabel,
        ...fieldGroupProps,
        ref: monthRef,
        children: getMonths(monthNames)
      }
    ) }),
    /* @__PURE__ */ jsx(Column, { children: /* @__PURE__ */ jsx(
      Dropdown,
      {
        id: yearId,
        value: currentValue.year || "",
        onChange: makeChangeHandler(onChange, value, "year"),
        onBlur: blurHandler,
        onFocus: focusHandler,
        tone,
        placeholder: yearLabel,
        "aria-label": yearLabel,
        ...fieldGroupProps,
        ref: yearRef,
        children: getYears(minYear, maxYear, ascendingYears)
      }
    ) })
  ] }) });
  return renderNativeInput ? nativeField : customFieldGroup;
};
MonthPicker.displayName = "MonthPicker";
export {
  FieldGroup,
  FieldLabel,
  FieldMessage,
  MonthPicker,
  mergeIds,
  tones
};
