import React, { useMemo, useCallback, useRef } from 'react'
import {
CloseButton,
Group,
Input,
Menu,
MultiSelect,
TextInput,
UnstyledButton,
} from '@mantine/core'
import { CustomSelectProps, Clicks } from '../types'
// import { IconChevronDown } from '@tabler/icons';
import { DEFAULT_LOCALE_EN } from '../locale'
import { classNames, sort } from '../utils'
import { parsePartArray, partToString, formatValue } from '../converter'
export default function CustomSelect(props: CustomSelectProps) {
const {
value,
grid = true,
labelText,
optionsList,
setValue,
locale,
className,
humanizeLabels,
disabled,
readOnly,
leadingZero,
clockFormat,
period,
unit,
periodicityOnDoubleClick,
mode,
...otherProps
} = props
const stringValue = useMemo(() => {
// console.log(stringValue)
if (value && Array.isArray(value)) {
return value.map((value: number) => value.toString())
}
}, [value])
// const stringLabel = useMemo(() => {
// console.log(stringValue)
// if (value && Array.isArray(value)) {
// return value.map((value: number) => optionsList![value])
// }
// }, [value])
// console.log(stringLabel)
// console.log(optionsList)
const options = useMemo(
() => {
if (optionsList) {
return optionsList.map((option, index) => {
const number = unit.min === 0 ? index : index + 1
return {
value: number.toString(),
label: option,
}
})
}
return [...Array(unit.total)].map((e, index) => {
const number = unit.min === 0 ? index : index + 1
return {
value: number.toString(),
label: formatValue(
number,
unit,
humanizeLabels,
leadingZero,
clockFormat
),
}
})
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[optionsList, leadingZero, humanizeLabels, clockFormat]
)
const localeJSON = JSON.stringify(locale)
const renderTag = useCallback(
(props: { value: string[] | undefined }) => {
const { value: itemValue } = props
if (!value || value[0] !== Number(itemValue)) {
return <>>
}
const parsedArray = parsePartArray(value, unit)
const cronValue = partToString(
parsedArray,
unit,
humanizeLabels,
leadingZero,
clockFormat
)
const testEveryValue = cronValue.match(/^\*\/([0-9]+),?/) || []
return (
{testEveryValue[1]
? `${locale.everyText || DEFAULT_LOCALE_EN.everyText} ${
testEveryValue[1]
}`
: cronValue}
)
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[value, localeJSON, humanizeLabels, leadingZero, clockFormat]
)
const simpleClick = useCallback(
(newValueOption: number | number[]) => {
// console.log({ newValueOption })
const newValueOptions = Array.isArray(newValueOption)
? sort(newValueOption)
: [newValueOption]
let newValue: number[] = newValueOptions
if (value) {
newValue = mode === 'single' ? [] : [...value]
newValueOptions.forEach((o) => {
const newValueOptionNumber = Number(o)
if (value.some((v) => v === newValueOptionNumber)) {
newValue = newValue.filter((v) => v !== newValueOptionNumber)
} else {
newValue = sort([...newValue, newValueOptionNumber])
}
})
}
if (newValue.length === unit.total) {
setValue([])
} else {
// console.log(newValue)
setValue(newValue)
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[setValue, value]
)
const simpleClickMantine = useCallback(
(newValueOption: string[]) => {
let newValue = newValueOption.map(Number)
newValue.sort((a, b) => a - b)
setValue(newValue)
// console.log(newValue)
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[setValue, value]
)
const doubleClick = useCallback(
(newValueOption: number) => {
if (newValueOption !== 0 && newValueOption !== 1) {
const limit = unit.total + unit.min
const newValue: number[] = []
for (let i = unit.min; i < limit; i++) {
if (i % newValueOption === 0) {
newValue.push(i)
}
}
const oldValueEqualNewValue =
value &&
newValue &&
value.length === newValue.length &&
value.every((v: number, i: number) => v === newValue[i])
const allValuesSelected = newValue.length === options.length
if (allValuesSelected) {
setValue([])
} else if (oldValueEqualNewValue) {
setValue([])
} else {
setValue(newValue)
}
} else {
setValue([])
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[value, options, setValue]
)
const clicksRef = useRef([])
const onOptionClick = useCallback(
(newValueOption: string) => {
// console.log(newValueOption)
if (!readOnly) {
const doubleClickTimeout = 300
const clicks = clicksRef.current
clicks.push({
time: new Date().getTime(),
value: Number(newValueOption),
})
const id = window.setTimeout(() => {
if (
periodicityOnDoubleClick &&
clicks.length > 1 &&
clicks[clicks.length - 1].time - clicks[clicks.length - 2].time <
doubleClickTimeout
) {
if (
clicks[clicks.length - 1].value ===
clicks[clicks.length - 2].value
) {
doubleClick(Number(newValueOption))
} else {
simpleClick([
clicks[clicks.length - 2].value,
clicks[clicks.length - 1].value,
])
}
} else {
simpleClick(Number(newValueOption))
}
clicksRef.current = []
}, doubleClickTimeout)
return () => {
window.clearTimeout(id)
}
}
},
[clicksRef, simpleClick, doubleClick, readOnly, periodicityOnDoubleClick]
)
// Used by the select clear icon
const onClear = useCallback(() => {
if (!readOnly) {
setValue([])
}
}, [setValue, readOnly])
const internalClassName = useMemo(
() =>
classNames({
'react-js-cron-select': true,
'react-js-cron-custom-select': true,
[`${className}-select`]: !!className,
}),
[className]
)
const dropdownClassNames = useMemo(
() =>
classNames({
'react-js-cron-select-dropdown': true,
[`react-js-cron-select-dropdown-${unit.type}`]: true,
'react-js-cron-custom-select-dropdown': true,
[`react-js-cron-custom-select-dropdown-${unit.type}`]: true,
[`react-js-cron-custom-select-dropdown-minutes-large`]:
unit.type === 'minutes' && period !== 'hour' && period !== 'day',
[`react-js-cron-custom-select-dropdown-minutes-medium`]:
unit.type === 'minutes' && (period === 'day' || period === 'hour'),
'react-js-cron-custom-select-dropdown-hours-twelve-hour-clock':
unit.type === 'hours' && clockFormat === '12-hour-clock',
'react-js-cron-custom-select-dropdown-grid': !!grid,
[`${className}-select-dropdown`]: !!className,
[`${className}-select-dropdown-${unit.type}`]: !!className,
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[className, grid, clockFormat, period]
)
return (
<>
}
styles={{ rightSection: { pointerEvents: 'none' } }}
rightSectionWidth={40}
onChange={(e) => simpleClickMantine(e)}
clearable
placeholder={otherProps?.placeholder?.toString()}
/>
>
)
}