/*
 * Copyright (C) 2026 Fluxer Contributors
 *
 * This file is part of Fluxer.
 *
 * Fluxer is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Fluxer is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
 */

import {clsx} from 'clsx';
import {observer} from 'mobx-react-lite';
import React from 'react';
import type {ConnectableElement} from 'react-dnd';
import {useDrop} from 'react-dnd';
import styles from './NullSpaceDropIndicator.module.css';
import {DND_TYPES, type DragItem, type DropResult} from './types/dnd';

interface NullSpaceDropIndicatorProps {
	isDraggingAnything: boolean;
	onChannelDrop?: (item: DragItem, result: DropResult) => void;
	variant?: 'top' | 'bottom';
}

export const NullSpaceDropIndicator = observer(
	({isDraggingAnything, onChannelDrop, variant = 'top'}: NullSpaceDropIndicatorProps) => {
		const [{isOver, canDrop}, dropRef] = useDrop(
			() => ({
				accept: [DND_TYPES.CHANNEL, DND_TYPES.CATEGORY],
				drop: (item: DragItem): DropResult => {
					const result: DropResult =
						variant === 'top'
							? {targetId: 'null-space', position: 'before', targetParentId: null}
							: {targetId: 'trailing-space', position: 'after', targetParentId: null};
					onChannelDrop?.(item, result);
					return result;
				},
				collect: (monitor) => ({
					isOver: monitor.isOver({shallow: true}),
					canDrop: monitor.canDrop(),
				}),
			}),
			[onChannelDrop, variant],
		);

		const dropConnectorRef = React.useCallback(
			(node: ConnectableElement | null) => {
				dropRef(node);
			},
			[dropRef],
		);

		return (
			<div
				ref={dropConnectorRef}
				className={clsx(styles.container, isDraggingAnything ? styles.containerDragging : styles.containerNotDragging)}
			>
				<div
					className={clsx(
						styles.indicator,
						isOver && canDrop && isDraggingAnything ? styles.indicatorVisible : styles.indicatorHidden,
					)}
				/>
			</div>
		);
	},
);
