import { useCallback, useEffect, useState } from 'react';
import { loadConfig } from '../utils';
import { useAlert } from '../context/AlertProvider';
import { alertTypes } from '../assets/data/types';
import * as APIConfigs from '../assets/data/apis'
import { callAPI } from '../utils/apiService';

export const useCommonSearch = (configPath) => {
	const [config, setConfig] = useState(null);
	const [searchParams, setSearchParams] = useState({});
	const [loading, setLoading] = useState(false);
	const [data, setData] = useState(null);
	const [configLoaded, setConfigLoaded] = useState(false);
	const { showToast } = useAlert();
	const [apiEndpoint, setApiEndpoint] = useState(null);
	const [apiConfig, setApiConfig] = useState(null);

	// 설정 파일 로드
	useEffect(() => {
		const fetchConfig = async () => {
			try {
				const configData = await loadConfig(configPath);
				setConfig(configData);

				// 초기 검색 파라미터 설정
				if (configData.initialSearchParams) {
					setSearchParams(configData.initialSearchParams);
				}

				// API 엔드포인트 설정 가져오기
				if (configData.apiInfo && configData.apiInfo.endpointName) {
					const endpointName = configData.apiInfo.endpointName;
					// API 설정 파일에서 엔드포인트 정보 찾기
					for (const configKey in APIConfigs) {
						const apiConfigData = APIConfigs[configKey];
						if (apiConfigData.endpoints && apiConfigData.endpoints[endpointName]) {
							setApiEndpoint(apiConfigData.endpoints[endpointName]);
							setApiConfig(apiConfigData);
							break;
						}
					}
				}

				setConfigLoaded(true);
			} catch (error) {
				console.error('Error loading search configuration:', error);
			}
		};

		fetchConfig();
	}, [configPath]);

	// 파라미터 값 변환 (날짜 등)
	const transformParams = useCallback((params) => {
		if (!config || !config.apiInfo || !config.apiInfo.paramTransforms) {
			return params;
		}

		const transformedParams = { ...params };

		// 파라미터 변환 적용
		config.apiInfo.paramTransforms.forEach(paramConfig => {
			if (paramConfig.param && paramConfig.transform) {
				const value = params[paramConfig.param];

				if (value) {
					if (paramConfig.transform === 'toISOString') {
						transformedParams[paramConfig.param] = new Date(value).toISOString();
					}
					// 필요시 다른 변환 로직 추가
				}
			}
		});

		return transformedParams;
	}, [config]);

	// 데이터 가져오기
	const fetchData = useCallback(async (params) => {
		if (!apiEndpoint || !apiConfig) return;

		try {
			setLoading(true);
			const transformedParams = transformParams(params);

			// 페이지네이션 필드 옵션
			const paginationOptions = {
				paginationType: config.paginationType
			};
			if (config.apiInfo?.pageField) {
				paginationOptions.pageField = config.apiInfo.pageField;
			}
			if (config.apiInfo?.pageSizeField) {
				paginationOptions.pageSizeField = config.apiInfo.pageSizeField;
			}
			if (config.apiInfo?.orderField) {
				paginationOptions.orderField = config.apiInfo.orderField;
			}
			if (config.paginationType === 'dynamodb' && config.apiInfo?.lastPageKeyField) {
				paginationOptions.lastPageKeyField = config.apiInfo.lastPageKeyField;
			}

			// API 호출
			const result = await callAPI(
				apiConfig,
				apiEndpoint,
				transformedParams,
				paginationOptions
			);

			// 에러 처리
			if (result.result && result.result.startsWith('ERROR')) {
				showToast(result.data.message, { type: alertTypes.error });
			}
			// console.log(result.data);
			setData(result.data || result);
			return result.data || result;
		} catch (error) {
			console.error(`Error fetching data:`, error);
			throw error;
		} finally {
			setLoading(false);
		}
	}, [apiEndpoint, apiConfig, config, transformParams, showToast]);

	const initialLoad = useCallback((config) => {
		// loadOnMount가 undefined 또는 true인 경우 true 반환
		return config?.apiInfo?.loadOnMount === undefined ||
			config?.apiInfo?.loadOnMount === true;
	}, []);

	// 초기 데이터 로드
	useEffect(() => {
		if (configLoaded && config && searchParams && apiEndpoint && config.apiInfo?.loadOnMount && initialLoad(config)) {
			fetchData(searchParams);
		}
	}, [configLoaded, config, searchParams, apiEndpoint, fetchData]);

	// 검색 파라미터 업데이트
	const updateSearchParams = useCallback((newParams) => {
		setSearchParams(prev => ({
			...prev,
			...newParams
		}));
	}, []);

	// 검색 처리
	const handleSearch = useCallback(async (newParams = {}, executeSearch = true) => {
		if (!config) return null;

		const pageField = 'currentPage'; // 항상 내부적으로는 currentPage 사용

		const updatedParams = {
			...searchParams,
			...newParams,
			[pageField]: newParams[pageField] || 1 // 새 검색 시 첫 페이지로 리셋
		};

		if (executeSearch && config.searchFields) {
			const requiredFields = config.searchFields.filter(field => field.required);

			for (const field of requiredFields) {
				if (!updatedParams[field.id] || updatedParams[field.id].trim() === '') {
					// 필수 필드가 비어있는 경우
					showToast('SEARCH_REQUIRED_WARNING', { type: alertTypes.warning });
					return null;
				}
			}
		}

		updateSearchParams(updatedParams);

		if (executeSearch) {
			return await fetchData(updatedParams);
		}
		return null;
	}, [searchParams, fetchData, config, updateSearchParams]);

	// 검색 초기화
	const handleReset = useCallback(async () => {
		if (!config || !config.initialSearchParams) return null;

		setSearchParams(config.initialSearchParams);
		setData(null);
		// return await fetchData(config.initialSearchParams);
	}, [config, fetchData]);

	// 페이지 변경
	const handlePageChange = useCallback(async (newPage) => {
		if (!config) return null;

		return await handleSearch({ currentPage: newPage }, true);
	}, [handleSearch, config]);

	// 페이지 크기 변경
	const handlePageSizeChange = useCallback(async (newSize) => {
		if (!config) return null;

		return await handleSearch({
			pageSize: newSize,
			currentPage: 1
		}, true);
	}, [handleSearch, config]);

	// 정렬 방식 변경
	const handleOrderByChange = useCallback(async (newOrder) => {
		if (!config) return null;

		return await handleSearch({ orderBy: newOrder }, true);
	}, [handleSearch, config]);

	return {
		config,
		searchParams,
		loading,
		data,
		handleSearch,
		handleReset,
		handlePageChange,
		handlePageSizeChange,
		handleOrderByChange,
		updateSearchParams,
		configLoaded
	};
};

export default useCommonSearch;