import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useMemo, forwardRef, useEffect, useRef } from 'react';
import styled from 'styled-components';
import { defaultThemeProp } from '../../../theme';
import { cap, createClassName, range, withTestIds } from '../../../utils';
import { useConfiguration, useConsolidatedRef, useFocusWithin, useTestIds } from '../../../hooks';
import FormField from '../../FormField';
import Select, { Option } from '../../Select';
import { StyledSelect } from '../../Select/Select';
import Flex from '../../Flex';
import { StyledFormControl } from '../../FormControl';
import { getMonthInputTestIds } from '../DateTime.test-ids';
import { StyledFormField, StyledFormFieldInfo } from '../../FormField/FormField';
import { parseToDate, getLocalizedMonths, getLocalizedYear } from './utils';
import StyledDateTime from './DateTime.styles';
export const StyledMonthInput = styled(StyledDateTime) `
  padding: 0;
  border: 0;
  background-color: transparent;

  ${StyledFormField}:enabled > &:focus-within {
    box-shadow: none;
  }

  ${StyledFormField} {
    > ${StyledSelect}:focus {
      z-index: 1;
    }

    :first-child {
      flex-grow: 1;
    }

    :first-child > ${StyledSelect} {
      border-start-end-radius: 0;
      border-end-end-radius: 0;
    }

    :last-child > ${StyledSelect} {
      width: max-content;
      margin-inline-start: -0.0625rem;
      border-start-start-radius: 0;
      border-end-start-radius: 0;
    }

    :first-child > ${StyledFormFieldInfo}, :last-child > ${StyledFormFieldInfo} {
      display: none;
    }
  }
`;
StyledMonthInput.defaultProps = defaultThemeProp;
const convertToCallbackParameter = (date, { month, year }) => {
    if ([month, year].every(Boolean)) {
        const resultDate = new Date(date);
        resultDate.setUTCFullYear(Number(year), Number(month));
        // handle month overflowing
        if (resultDate.getUTCMonth() !== Number(month)) {
            resultDate.setUTCDate(0);
        }
        return {
            valueAsISOString: resultDate.toISOString(),
            valueAsTimestamp: resultDate.getTime()
        };
    }
    if ([year, month].every(p => !p)) {
        return {
            valueAsISOString: undefined,
            valueAsTimestamp: undefined
        };
    }
    return {
        valueAsISOString: '',
        valueAsTimestamp: NaN,
        state: 'incomplete'
    };
};
const MonthInput = forwardRef(function MonthInput(props, ref) {
    const { locale } = useConfiguration();
    const { testId, value, min, max, id, label, labelHidden, innerLabelsHidden = true, info, status, required, readOnly, disabled, onChange, onFocus, onBlur, autoFocus, additionalInfo, className, ...restProps } = props;
    const testIds = useTestIds(testId, getMonthInputTestIds);
    const date = value ? parseToDate(value) : undefined;
    const dateToGetFullYearFrom = date ?? new Date();
    const minDate = parseToDate(min ??
        new Date(dateToGetFullYearFrom).setUTCFullYear(dateToGetFullYearFrom.getUTCFullYear() - 10));
    const maxDate = parseToDate(max ??
        new Date(dateToGetFullYearFrom).setUTCFullYear(dateToGetFullYearFrom.getUTCFullYear() + 10));
    const minYear = minDate.getUTCFullYear();
    const maxYear = maxDate.getUTCFullYear();
    const years = range(minYear, maxYear);
    const months = useMemo(() => getLocalizedMonths(locale), [locale]);
    const monthSelectRef = useRef(null);
    const yearSelectRef = useRef(null);
    useEffect(() => {
        if (monthSelectRef.current && yearSelectRef.current) {
            monthSelectRef.current.value = date?.getUTCMonth().toString() ?? '';
            yearSelectRef.current.value = date?.getUTCFullYear().toString() ?? '';
        }
    }, [date?.toDateString()]);
    const pickParts = () => {
        return {
            month: monthSelectRef.current?.value || '',
            year: yearSelectRef.current?.value || ''
        };
    };
    const onFocusChange = (focused) => {
        const callbackParam = convertToCallbackParameter(date ? new Date(date) : new Date(), pickParts());
        if (onFocus && focused)
            onFocus(callbackParam);
        else if (onBlur && !focused)
            onBlur(callbackParam);
    };
    const onSelectChange = () => {
        onChange?.(convertToCallbackParameter(date ? new Date(date) : new Date(), pickParts()));
    };
    const containerRef = useConsolidatedRef(ref);
    useFocusWithin([containerRef], onFocusChange);
    const isMonthOptionDisabled = (monthIndex) => {
        const year = yearSelectRef.current && yearSelectRef.current.value
            ? parseInt(yearSelectRef.current.value, 10)
            : new Date().getUTCFullYear();
        return ((year === minDate.getUTCFullYear() && monthIndex < minDate.getUTCMonth()) ||
            (year === maxDate.getUTCFullYear() && monthIndex > maxDate.getUTCMonth()));
    };
    const monthOptions = months.map((month, index) => (_jsx(Option, { disabled: isMonthOptionDisabled(index), value: index.toString(), children: months[index] }, month)));
    const yearOptions = years.map(year => (_jsx(Option, { value: year.toString(), children: getLocalizedYear(year, locale).toString() }, year.toString())));
    const displayNames = useMemo(() => new Intl.DisplayNames(locale, {
        style: 'long',
        type: 'dateTimeField'
    }), [locale]);
    const Month = (_jsxs(Select, { "data-testid": testIds.controlMonth, label: cap(displayNames.of('month')), labelHidden: innerLabelsHidden, ref: monthSelectRef, "aria-label": displayNames.of('month'), readOnly: readOnly, required: required, onChange: onSelectChange, status: status, disabled: disabled, autoFocus: autoFocus, children: [!required && _jsx(Option, { children: " " }, 'null'), monthOptions] }, 'month'));
    const Year = (_jsxs(Select, { "data-testid": testIds.controlYear, label: cap(displayNames.of('year')), labelHidden: innerLabelsHidden, ref: yearSelectRef, "aria-label": displayNames.of('year'), readOnly: readOnly, required: required, onChange: onSelectChange, status: status, disabled: disabled, children: [!required && _jsx(Option, { children: " " }, 'null'), yearOptions] }, 'year'));
    const Comp = (_jsxs(Flex, { as: StyledMonthInput, forwardedAs: StyledFormControl, container: { alignItems: 'center', wrap: 'nowrap' }, ref: containerRef, status: status, disabled: disabled, readOnly: readOnly, ...restProps, className: createClassName('month-input', className), children: [Month, Year] }));
    return label ? (_jsx(FormField, { testId: testIds, as: 'fieldset', label: label, labelHidden: labelHidden, id: id, info: info, readOnly: readOnly, status: status, required: required, disabled: disabled, additionalInfo: additionalInfo, children: Comp })) : (Comp);
});
export default withTestIds(MonthInput, getMonthInputTestIds);
//# sourceMappingURL=MonthInput.js.map