'use client'

import clsx from 'clsx'
import { useTranslations } from 'next-intl'
import { useRouter } from 'next/navigation'
import {
	ChangeEvent,
	type ComponentProps,
	type ReactNode,
	useEffect,
	useRef,
	useState
} from 'react'

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

import { Button, Input, Select, Table } from '@/components/atoms'

import { IColumnItem, IFilterQuery, IPaginationOptions } from '@/types'

import { dialogStyles, headerStyles, rootStyles } from './DataTable.styles'

import { CreationModal } from './CreationModal'
import { useDebounce } from '@/hooks'
import { _, addParam, getParams, removeParam } from '@/utils'

type DataTableProps = ComponentProps<'div'> & {
	columns: IColumnItem[]
	dataSource: any[]
	pagination: IPaginationOptions
	getData: (data: Record<string, any>) => void
	filterQuery: IFilterQuery
	listName?: string
	creation: ReactNode
}

export function DataTable({
	columns,
	dataSource,
	pagination,
	getData,
	filterQuery,
	listName,
	creation,
	className
}: DataTableProps) {
	const tl = useTranslations(listName)
	const t = useTranslations()
	//
	const router = useRouter()
	//
	const [q, setQ] = useState<string>()
	const [limit, setLimit] = useState('10')
	const [modalOpen, setModalOpen] = useState(false)
	const debouncedQ = useDebounce(q, 350)
	const isInit = useRef(false)
	//
	useEffect(() => {
		const { q, limit } = getParams()
		if (q) setQ(q)
		if (limit) setLimit(limit)
	}, [])
	//
	const openHandler = () => {
		setModalOpen(true)
	}
	//
	const cancelHandler = () => {
		setModalOpen(false)
	}
	//
	const changeLimitHandler = (value: string) => {
		if (value === '10') {
			removeParam(router, 'limit')
		} else {
			addParam(router, 'limit', value)
		}
		//
		setTimeout(() => removeParam(router, 'page'), 350)
		//
		setLimit(value)
		//
		getData({
			limit: +value,
			page: 0
		})
	}
	//
	useEffect(() => {
		if (debouncedQ) {
			addParam(router, 'q', debouncedQ)
		} else {
			removeParam(router, 'q')
		}

		if (!isInit.current) {
			if (!_.isUndefined(debouncedQ)) {
				setTimeout(() => removeParam(router, 'page'), 350)
				//
				getData({
					q: debouncedQ,
					page: 0
				})
			}

			isInit.current = true
		}
	}, [debouncedQ])
	//
	return (
		<div className={clsx(rootStyles, className)}>
			<div className={headerStyles}>
				<Select
					onValueChange={changeLimitHandler}
					value={limit}
					className='w-25'
				>
					<Select.Item value='1'>1</Select.Item>
					<Select.Item value='2'>2</Select.Item>
					<Select.Item value='3'>3</Select.Item>
					<Select.Item value='10'>10</Select.Item>
					<Select.Item value='50'>50</Select.Item>
					<Select.Item value='100'>100</Select.Item>
				</Select>
				<Button className='mr-auto' onClick={openHandler}>
					<TbPlus /> {listName ? tl('add') : t('add')}
				</Button>
				<Input.Search
					value={q || ''}
					onChange={(e: ChangeEvent<HTMLInputElement>) =>
						setQ(e.target.value)
					}
					placeholder={t('search')}
					className='ml-auto w-65!'
				/>
				<Select defaultValue='all' className='w-38'>
					<Select.Item value='all'>{t('all')}</Select.Item>
					<Select.Item value='current'>{t('only-mine')}</Select.Item>
					<Select.Item value='not-current'>
						{t('besides-mine')}
					</Select.Item>
				</Select>
			</div>
			<Table
				dataSource={dataSource}
				columns={columns}
				onRowSelection={() => {}}
				pagination={{
					...pagination,
					name: listName,
					limit: +limit
				}}
				getData={getData}
				filterQuery={filterQuery}
				actions
			/>
			<CreationModal
				open={modalOpen}
				onCancel={cancelHandler}
				onEscapeKeyDown={cancelHandler}
				className={dialogStyles}
			>
				{creation}
			</CreationModal>
		</div>
	)
}
