import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
import { useLayoutEffect, useState, forwardRef } from 'react';
import styled, { css } from 'styled-components';
import Flex from '../../Flex';
import { defaultThemeProp } from '../../../theme';
import Text from '../../Text';
import { cap } from '../../../utils';
import { getDateOfISOWeek, getWeek, parseToDate, toUTCDateString } from '../Input/utils';
import { useConfiguration, useConsolidatedRef, useFocusWithin } from '../../../hooks';
import { CALENDAR_TYPES } from '../Input/local';
import { StyledColumnLabel, StyledPick } from './Calendar.styles';
import { getWeeksOfMonth } from './utils';
export const StyledWeekNumbers = styled.div `
  margin-inline-end: ${props => props.theme.base.spacing};
  color: rgba(0, 0, 0, 0.75);
`;
StyledWeekNumbers.defaultProps = defaultThemeProp;
const StyledWeekNumber = styled(StyledPick)(props => {
    const { theme: { base: { 'border-radius': borderRadius } } } = props;
    return css `
    &:disabled {
      &:nth-child(2) {
        border-radius: calc(0.5 * ${borderRadius}) calc(0.5 * ${borderRadius}) 0 0;
      }
      &:last-child {
        border-radius: 0 0 calc(0.5 * ${borderRadius}) calc(0.5 * ${borderRadius});
      }
    }
  `;
});
StyledWeekNumber.defaultProps = defaultThemeProp;
const Weeks = forwardRef(function Weeks(props, ref) {
    const { selected, current = selected ? new Date(selected.getTime()) : new Date(), calendarType = CALENDAR_TYPES.ISO_8601, onSelect, onFocus, disabled = false, size = 'short' } = props;
    const { locale } = useConfiguration();
    const [focusedWeek, setFocusedWeek] = useState(current);
    useLayoutEffect(() => {
        setFocusedWeek(current);
    }, [current.getUTCFullYear(), current.getUTCMonth()]);
    let newFocused;
    const onKeyDown = (ev) => {
        if (['ArrowUp', 'ArrowDown', 'Enter'].includes(ev.key))
            ev.preventDefault();
        switch (ev.key) {
            case 'ArrowUp':
                newFocused = new Date(focusedWeek);
                newFocused.setUTCDate(focusedWeek.getUTCDate() - 7);
                setFocusedWeek(newFocused);
                onFocus?.(newFocused);
                break;
            case 'ArrowDown':
                newFocused = new Date(focusedWeek);
                newFocused.setUTCDate(focusedWeek.getUTCDate() + 7);
                setFocusedWeek(newFocused);
                onFocus?.(newFocused);
                break;
            case 'Enter':
                onSelect?.(focusedWeek);
                break;
            default:
        }
    };
    const containerRef = useConsolidatedRef(ref);
    const hasFocus = useFocusWithin([containerRef]);
    const min = props.min ? parseToDate(props.min) : -Infinity;
    const max = props.max ? parseToDate(props.max) : Infinity;
    const isDisabled = (day) => {
        return disabled || Number(min) > day.getTime() || day.getTime() > Number(max);
    };
    const isChecked = (day) => {
        return (selected &&
            toUTCDateString(day) ===
                toUTCDateString(getDateOfISOWeek(getWeek(selected, calendarType), selected.getFullYear())));
    };
    const isFocused = (day) => {
        return (toUTCDateString(day) ===
            toUTCDateString(getDateOfISOWeek(getWeek(focusedWeek, calendarType), focusedWeek.getFullYear())));
    };
    const displayNames = new Intl.DisplayNames(locale, {
        style: 'long',
        type: 'dateTimeField'
    });
    const displayNamesShort = new Intl.DisplayNames(locale, {
        style: 'short',
        type: 'dateTimeField'
    });
    const weeks = getWeeksOfMonth(current, calendarType).map(({ weekNo, weekYear }) => {
        const dateOfISOWeek = getDateOfISOWeek(weekNo, weekYear);
        return (_jsxs(StyledWeekNumber, { variant: 'simple', icon: false, type: 'button', loading: false, ref: isFocused(dateOfISOWeek)
                ? (focusedRef) => {
                    if (hasFocus)
                        focusedRef?.focus();
                }
                : undefined, tabIndex: isFocused(dateOfISOWeek) ? 0 : -1, disabled: isDisabled(dateOfISOWeek), "aria-selected": isChecked(dateOfISOWeek) || undefined, "aria-label": `${displayNames.of('weekOfYear')} ${weekNo.toString()} ${weekYear.toString()}`, onClick: () => {
                onSelect?.(dateOfISOWeek);
            }, children: [size === 'long' && `${cap(displayNames.of('weekOfYear'))} `, weekNo.toString()] }, weekNo));
    });
    const label = size === 'short' ? (_jsx(Text, { as: StyledColumnLabel, forwardedAs: 'abbr', title: cap(displayNames.of('weekOfYear')), children: cap(displayNamesShort.of('weekOfYear')) })) : (_jsx(Text, { as: StyledColumnLabel, children: cap(displayNames.of('weekOfYear')) }));
    return (_jsxs(Flex, { as: StyledWeekNumbers, container: { direction: 'column' }, ref: containerRef, onKeyDown: onKeyDown, children: [label, weeks] }));
});
export default Weeks;
//# sourceMappingURL=Weeks.js.map