'use client'

import { useMask } from '@react-input/mask'
import dayjs from 'dayjs'
import { ChangeEvent, type ComponentProps, useEffect, useState } from 'react'
import { DateRange, DayPicker } from 'react-day-picker'

import { TbCalendarMonth } from 'react-icons/tb'

import { Calendar, Input, Popover } from '@/components/atoms'

import {
	iconStyles,
	inputStyles,
	type InputStylesProps,
	rootStyles
} from './DatePicker.styles'

import {
	getAlignOffset,
	getMask,
	getPlaceholder,
	getSideOffset
} from './DatePicker.utils'
import { _ } from '@/utils'

type DatePickerProps = {
	onSelect?: (value: DateRange) => void
	defaultSelected?: DateRange
	defaultOpen?: boolean | { isOpen: boolean; delay: number }
} & ComponentProps<typeof DayPicker> &
	InputStylesProps

export function DatePicker({
	defaultOpen,
	mode = 'single',
	size = 'md',
	onSelect,
	defaultSelected
}: DatePickerProps) {
	const [open, setOpen] = useState(
		_.isObject(defaultOpen) ? false : defaultOpen
	)
	const [date, setDate] = useState('')
	//
	const inputRef = useMask({
		mask: getMask(mode),
		replacement: { _: /\d/ },
		showMask: false,
		modify: data => {
			return { showMask: !!data.data }
		}
	})
	//
	useEffect(() => {
		if (_.isObject(defaultOpen) && defaultOpen?.delay) {
			const timer = setTimeout(() => {
				setOpen(true)
			}, defaultOpen.delay)

			return () => clearTimeout(timer)
		}
	}, [])
	//
	useEffect(() => {
		if (defaultSelected) {
			const from = defaultSelected.from
				? dayjs(defaultSelected.from).format('DD/MM/YYYY')
				: ''
			const to = defaultSelected.to
				? dayjs(defaultSelected.to).format('DD/MM/YYYY')
				: ''
			setDate(from && to ? `${from} — ${to}` : '')
		}
	}, [defaultSelected])
	//
	const onSelectHandler = (value: DateRange) => {
		const from = value.from ? dayjs(value.from).format('DD/MM/YYYY') : ''
		const to = value.to ? dayjs(value.to).format('DD/MM/YYYY') : ''
		setDate(from && to ? `${from} — ${to}` : '')
		onSelect?.(value)
	}
	//
	return (
		<div className={rootStyles}>
			<Input
				value={date}
				onChange={(e: ChangeEvent<HTMLInputElement>) =>
					setDate(e.target.value)
				}
				sizes={size}
				ref={inputRef}
				className={inputStyles({ size })}
				placeholder={getPlaceholder(mode)}
			/>
			<Popover
				open={open}
				onOpenChange={setOpen}
				trigger={<TbCalendarMonth className={iconStyles({ size })} />}
				align='end'
				sideOffset={getSideOffset(size!)}
				alignOffset={getAlignOffset(size!)}
				arrow={false}
			>
				<Calendar
					mode={mode as any}
					size={size}
					onSelect={onSelectHandler}
					defaultSelected={defaultSelected}
				/>
			</Popover>
		</div>
	)
}
