import React, { useMemo } from 'react';
import { getTagColorStyle } from '../../utils/colors';
import { writeTagTransferData } from '../tagTransfer';
import type { DocumentTag } from '../../types/documents';
import type { Identifier } from '../../types/identifiers';

interface DocumentTagsProps {
    tags: DocumentTag[];
    tagLookupById?: Map<Identifier, DocumentTag> | null;
    onTagClick?: (tagId: Identifier) => void;
    docId: Identifier;
    onDocumentTagDetach?: (docId: Identifier, tagId: Identifier) => void;
    onTagDragStart?: (event: React.DragEvent<HTMLElement>, tagId: Identifier) => void;
    onTagDragEnd?: (event: React.DragEvent<HTMLElement>) => void;
}

const DocumentTags: React.FC<DocumentTagsProps> = ({
    tags,
    tagLookupById,
    onTagClick,
    docId,
    onDocumentTagDetach,
    onTagDragStart,
    onTagDragEnd,
}) => {
    const sortedTags = useMemo(() => {
        return [...tags].sort((a, b) => {
            const labelA = (a.label || '').toLowerCase();
            const labelB = (b.label || '').toLowerCase();
            return labelA.localeCompare(labelB);
        });
    }, [tags]);

    if (tags.length === 0) {
        return null;
    }

    return (
        <>
            {sortedTags.map((tag, index) => {
                const colorSource = tag?.color || tagLookupById?.get(tag.id)?.color;
                const style = getTagColorStyle(colorSource);
                const tagId = tag?.id ?? null;
                const clickable = tagId != null && typeof onTagClick === 'function';
                const key = tagId ?? `${docId}-tag-${index}`;

                return (
                    <span
                        key={key}
                        className="badge tag-chip"
                        style={style || undefined}
                        title={tag.label}
                        role={clickable ? 'button' : undefined}
                        onClick={clickable ? (event) => {
                            event.stopPropagation();
                            if (tagId == null) return;
                            onTagClick?.(tagId);
                        } : undefined}
                        draggable
                        onDragStart={(event) => {
                            event.stopPropagation();
                            try {
                                if (event.dataTransfer) {
                                    event.dataTransfer.effectAllowed = 'copyMove';
                                }
                            } catch (error) {
                                console.warn('[documents] Failed to configure drag effect', error);
                            }
                            writeTagTransferData(event.dataTransfer, tag, docId);
                            if (tagId) {
                                onTagDragStart?.(event, tagId);
                            }
                        }}
                        onDragEnd={(event) => {
                            event.stopPropagation();
                            if (event.dataTransfer.dropEffect === 'move' && tagId && onDocumentTagDetach) {
                                onDocumentTagDetach(docId, tagId);
                            }
                            onTagDragEnd?.(event);
                        }}
                        onKeyDown={clickable ? (event) => {
                            if (event.key === 'Enter' || event.key === ' ') {
                                event.preventDefault();
                                event.stopPropagation();
                                if (tagId == null) return;
                                onTagClick?.(tagId);
                            }
                        } : undefined}
                    >
                        {tag.label}
                    </span>
                );
            })}
        </>
    );
};

export default DocumentTags;
