import { useRef } from 'react';
import { useDrag, useDrop } from 'react-dnd';

import type { JourneyWidgetId, JourneyWidgetSize } from './widget-registry';
import { JOURNEY_WIDGET_MAP } from './widget-registry';

export const JOURNEY_WIDGET_DND_TYPE = 'JOURNEY_WIDGET';

type DragItem = { id: JourneyWidgetId; index: number };

interface JourneyWidgetShellProps {
    id: JourneyWidgetId;
    index: number;
    size: JourneyWidgetSize;
    onMove: (dragIndex: number, hoverIndex: number) => void;
    onChangeSize: (id: JourneyWidgetId, size: JourneyWidgetSize) => void;
    onRemove: (id: JourneyWidgetId) => void;
    children: React.ReactNode;
}

const JourneyWidgetShell = ({
    id,
    index,
    size,
    onMove,
    onChangeSize,
    onRemove,
    children,
}: JourneyWidgetShellProps) => {
    const ref = useRef<HTMLDivElement | null>(null);
    const def = JOURNEY_WIDGET_MAP[id];

    const [{ isDragging }, drag, preview] = useDrag({
        type: JOURNEY_WIDGET_DND_TYPE,
        item: { id, index } as DragItem,
        collect: (monitor) => ({
            isDragging: monitor.isDragging(),
        }),
    });

    const [, drop] = useDrop({
        accept: JOURNEY_WIDGET_DND_TYPE,
        hover(item: DragItem) {
            if (!ref.current || item.id === id) return;
            if (item.index === index) return;
            onMove(item.index, index);
            item.index = index;
        },
    });

    preview(drop(ref));

    return (
        <div
            ref={ref}
            className={`panel h-full ${size === 'full' ? 'col-span-12' : 'col-span-12 md:col-span-6'} ${isDragging ? 'opacity-50' : ''
                }`}
        >
            <div className="mb-3 flex flex-wrap items-center justify-between gap-2 border-b border-gray-100 pb-2">
                <div className="flex items-center gap-2 min-w-0">
                    <span
                        ref={drag as unknown as React.Ref<HTMLSpanElement>}
                        className="cursor-grab active:cursor-grabbing select-none rounded border border-gray-200 px-2 py-0.5 text-xs text-gray-500 hover:bg-gray-50"
                        title="Drag untuk pindah"
                        aria-label="Drag widget"
                    >
                        ⋮⋮⋮
                    </span>
                    <div className="min-w-0">
                        <h4 className="font-semibold truncate">{def?.title || id}</h4>
                        {def?.description ? (
                            <p className="text-xs text-gray-400 truncate">{def.description}</p>
                        ) : null}
                    </div>
                </div>
                <div className="flex items-center gap-2">
                    <select
                        className="form-select text-xs py-1"
                        value={size}
                        onChange={(e) => onChangeSize(id, e.target.value as JourneyWidgetSize)}
                        aria-label="Ukuran widget"
                    >
                        <option value="half">Half</option>
                        <option value="full">Full</option>
                    </select>
                    <button
                        type="button"
                        className="btn btn-outline-danger btn-sm"
                        onClick={() => onRemove(id)}
                    >
                        Hapus
                    </button>
                </div>
            </div>
            <div>{children}</div>
        </div>
    );
};

export default JourneyWidgetShell;
