

import {
	useState,
	useEffect,
	useRef
} from '@wordpress/element';

import { useControlSettingSet } from '../_hooks';


import {
	DndContext,
	closestCenter,
	KeyboardSensor,
	PointerSensor,
	useSensor,
	useSensors,
	type DragEndEvent,
} from '@dnd-kit/core';

import {
	arrayMove,
	SortableContext,
	sortableKeyboardCoordinates,
	verticalListSortingStrategy,
} from '@dnd-kit/sortable';

// 要素内のみで制限するようにする
import { restrictToParentElement } from "@dnd-kit/modifiers";

import SortableItem from './SortableItem';

import { __ } from '@wordpress/i18n';

type Props = {
	values: SortItems,
	title: string,
	description?: string,
	onChange: (newValues: string[]) => void,
	disabledSort?: string[],
}

export default function ApuraSortable({values, title, description, onChange, disabledSort}: Props) {
	const [sortItems, setSortItems] = useState<SortItems>(values);
	const [isInitialized, setIsInitialized] = useState(false);
	const initTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);

	// センサーの初期化を遅延実行
	const sensors = useSensors(
		useSensor(PointerSensor, {
			activationConstraint: {
				distance: 8, // 8px移動してからドラッグ開始
			},
		}),
		useSensor(KeyboardSensor, {
			coordinateGetter: sortableKeyboardCoordinates,
		})
	);

	// コンポーネントマウント後の遅延初期化
	useEffect(() => {
		// iframe環境での初期化を少し遅延させる
		initTimeoutRef.current = setTimeout(() => {
			setIsInitialized(true);
		}, 100);

		return () => {
			if (initTimeoutRef.current) {
				clearTimeout(initTimeoutRef.current);
			}
		};
	}, []);

	// valuesが変更された時の処理
	useEffect(() => {
		setSortItems(values);
	}, [values]);


	function handleDragEnd(event: DragEndEvent) {
		const {active, over} = event;

		if (active.id !== over?.id) {
			setSortItems((items) => {
				const oldIndex = items.findIndex(
					(item) => item.id === active.id
				);
				const newIndex = items.findIndex(
					(item) => item.id === over.id
				);

				return arrayMove(items, oldIndex, newIndex);
			});
		}
	}

	function handleItemActive(id:string) {
		const newValues = sortItems.map((_item, i) =>{
			if (_item.id === id) {
				// Return a new number
				return {
					..._item,
					isActive: !_item.isActive,
				};
			} else {
				 // No change
				return _item;
			}
		});
		// Re-render with the new array
		setSortItems(newValues);
	}

	// Update.
	useEffect(() => {
		const result = sortItems.flatMap(obj => obj.isActive ? obj.id : []);
		onChange(result);
	}, [sortItems, onChange]);



	return (
		<div className='apura-sortable-control'>
			<div className='apura-control-title'>{title}</div>
			{description && <div className='customize-control-description'>{description}</div>}
			{isInitialized ? (
				<DndContext
					autoScroll={false}
					sensors={sensors}
					collisionDetection={closestCenter}
					onDragEnd={handleDragEnd}
					modifiers={[restrictToParentElement]}
				>
					<SortableContext
						items={sortItems}
						strategy={verticalListSortingStrategy}
					>
						{sortItems.map(item => {
							return (
							<SortableItem
								key={item.id}
								id={item.id}
								label={item.label}
								value={item.value}
								sortLabel={ __( 'Sort by drag and drop', 'apura' )}
								isActive={item.isActive}
								disabled={disabledSort?.includes(item.id)}
								subControls={item.subControls}
								onActive={() => handleItemActive(item.id)}
							/>
							)
						})}
					</SortableContext>
				</DndContext>
			) : (
				// 初期化中の表示（DndContextなし）
				<div className="apura-sortable-loading">
					{sortItems.map(item => (
						<SortableItem
							key={item.id}
							id={item.id}
							label={item.label}
							value={item.value}
							sortLabel={ __( 'Sort by drag and drop', 'apura' )}
							isActive={item.isActive}
							disabled={true} // 初期化中はドラッグ無効
							subControls={item.subControls}
							onActive={() => handleItemActive(item.id)}
						/>
					))}
				</div>
			)}
		</div>
	);
}
