import { useCallback, useEffect, useRef, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { AuthModal } from '../components/common';
import { authList } from '../store/authList';
import { INITIAL_CURRENT_PAGE, INITIAL_PAGE_SIZE } from '../assets/data/adminConstants';
import { PageSkeleton } from '../components/Skeleton/PageSkeleton';

export const useDateTimeState = (initialDate = '') => {
	const [date, setDate] = useState(initialDate);
	const [hour, setHour] = useState('00');
	const [minute, setMinute] = useState('00');

	const setDateTime = (newDate, newHour = hour, newMinute = minute) => {
		const dateObj = newDate ? new Date(newDate) : new Date();
		const result = new Date(
			dateObj.getFullYear(),
			dateObj.getMonth(),
			dateObj.getDate(),
			newHour,
			newMinute
		);
		setDate(result);
		setHour(newHour);
		setMinute(newMinute);
		return result;
	};

	return [date, hour, minute, setDateTime, setHour, setMinute];
};

export const useModal = (initialModals = {}) => {
	const [modalState, setModalState] = useState(
		Object.keys(initialModals).reduce((acc, key) => ({
			...acc,
			[`${key}Modal`]: initialModals[key] || 'hidden'
		}), {})
	);

	const handleModalView = (type) => {
		setModalState((prevState) => ({
			...prevState,
			[`${type}Modal`]: 'view'
		}));
	};

	const handleModalClose = (type) => {
		setModalState((prevState) => ({
			...prevState,
			[`${type}Modal`]: 'hidden'
		}));
	};

	return {
		modalState,
		handleModalView,
		handleModalClose
	};
};

export const withAuth = (requiredAuth) => (WrappedComponent) => {
	return function WithAuthComponent(props) {
		const userInfo = useRecoilValue(authList);

		if (!userInfo || !userInfo.auth_list) {
			return (
				<PageSkeleton />
			);
		}

		const hasRequiredAuth = userInfo.auth_list &&
			userInfo.auth_list.some(auth => auth.id === requiredAuth);

		if (!hasRequiredAuth) {
			return <AuthModal />;
		}

		return <WrappedComponent {...props} />;
		// return <PageSkeleton />
	};
};

export const useTable = (tableData = [], options = {mode: 'multi'}) => {
	const [selectedRows, setSelectedRows] = useState([]);
	const tableDataRef = useRef(tableData);

	// tableData가 변경될 때 선택된 행 초기화
	useEffect(() => {
		const hasDataChanged =
			tableData.length !== tableDataRef.current.length ||
			tableData.some((item, index) =>
				tableDataRef.current[index]?.id !== item.id
			);

		setSelectedRows([]);
		if (hasDataChanged) {
			tableDataRef.current = tableData;
		}
	}, [tableData]);

	// 단일 행 선택/해제
	const handleSelectRow = useCallback((e, rowData) => {
		const checked = e.target.checked;
		setSelectedRows(prev => {
			if (checked) {
				if (options.mode === 'single') {
					return [rowData];
				}
				return [...prev, rowData];
			} else {
				return prev.filter(row => row.id !== rowData.id);
			}
		});
	}, []);

	// 전체 선택/해제
	const handleSelectAll = useCallback(() => {
		if (options.mode === 'single') return;

		setSelectedRows(prev =>
			prev.length === tableData.length ? [] : [...tableData]
		);
	}, [tableData]);

	// 특정 행이 선택되었는지 확인
	const isRowSelected = useCallback((rowId) => {
		return selectedRows.some(row => row.id === rowId);
	}, [selectedRows]);

	// 전체 선택 여부 확인
	const isAllSelected = tableData.length > 0 && selectedRows.length === tableData.length;

	// 선택된 행 삭제
	const removeSelectedRows = useCallback(() => {
		setSelectedRows([]);
	}, []);

	return {
		selectedRows,
		handleSelectRow,
		handleSelectAll,
		isRowSelected,
		isAllSelected,
		removeSelectedRows
	};
};

export const useDataFetch = (fetchFunction, dependencies = [], initialState = null) => {
	const [data, setData] = useState(initialState);
	const [loading, setLoading] = useState(false);
	const [error, setError] = useState(null);

	const fetchData = async (...params) => {
		try {
			setLoading(true);
			setError(null);
			const result = await fetchFunction(...params);
			setData(result);
			return result;
		} catch (err) {
			setError(err);
			throw err;
		} finally {
			setLoading(false);
		}
	};

	useEffect(() => {
		fetchData();
	}, dependencies);

	return {
		data,
		loading,
		error,
		refetch: fetchData,
		setData
	};
};