// ProjectTimeline - Modern split-panel workflow component for projects

// SVG Status Icons
const StatusIcons = {
    in_attesa: (
        <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <circle cx="12" cy="12" r="10" strokeWidth="2" />
        </svg>
    ),
    in_corso: (
        <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
        </svg>
    ),
    completato: (
        <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
        </svg>
    ),
    bloccato: (
        <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
        </svg>
    ),
    annullato: (
        <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
        </svg>
    ),
};

// Status configuration
const getStatusConfig = (status) => {
    const configs = {
        in_attesa: {
            label: 'In Attesa',
            bgColor: 'bg-slate-100',
            textColor: 'text-slate-600',
            borderColor: 'border-slate-300',
            dotColor: 'bg-slate-400',
            iconColor: 'text-slate-400',
        },
        in_corso: {
            label: 'In Corso',
            bgColor: 'bg-blue-50',
            textColor: 'text-blue-700',
            borderColor: 'border-blue-300',
            dotColor: 'bg-blue-500',
            iconColor: 'text-blue-500',
        },
        completato: {
            label: 'Completato',
            bgColor: 'bg-green-50',
            textColor: 'text-green-700',
            borderColor: 'border-green-300',
            dotColor: 'bg-green-500',
            iconColor: 'text-green-500',
        },
        bloccato: {
            label: 'Bloccato',
            bgColor: 'bg-red-50',
            textColor: 'text-red-700',
            borderColor: 'border-red-300',
            dotColor: 'bg-red-500',
            iconColor: 'text-red-500',
        },
        annullato: {
            label: 'Annullato',
            bgColor: 'bg-gray-50',
            textColor: 'text-gray-500',
            borderColor: 'border-gray-200',
            dotColor: 'bg-gray-400',
            iconColor: 'text-gray-400',
        },
    };
    return configs[status] || configs.in_attesa;
};

const statusOptions = [
    { value: 'in_attesa', label: 'In Attesa' },
    { value: 'in_corso', label: 'In Corso' },
    { value: 'completato', label: 'Completato' },
    { value: 'bloccato', label: 'Bloccato' },
    { value: 'annullato', label: 'Annullato' },
];

// Available emoji reactions
const REACTION_EMOJIS = ['👍', '❤️', '😄', '🎉', '👀', '🚀'];

// Compact step list item
function StepListItem({ step, isSelected, onClick, formatRelativeTime }) {
    const config = getStatusConfig(step.status);
    const commentCount = step.comments?.length || 0;
    const attachmentCount = (step.attachments?.length || 0) +
        (step.comments || []).reduce((sum, c) => sum + (c.attachments?.length || 0), 0);

    return (
        <button
            onClick={onClick}
            className={`w-full text-left p-3 rounded-lg transition-all duration-200 border ${
                isSelected
                    ? 'bg-brand-50 border-brand-200 shadow-sm'
                    : 'bg-white border-transparent hover:bg-slate-50 hover:border-slate-200'
            }`}
        >
            <div className="flex items-center gap-3">
                {/* Status icon */}
                <div className={`flex-shrink-0 ${config.iconColor}`}>
                    {StatusIcons[step.status]}
                </div>

                {/* Step info */}
                <div className="flex-1 min-w-0">
                    <div className="flex items-center gap-2">
                        <span className={`text-sm font-medium truncate ${isSelected ? 'text-brand-700' : 'text-slate-700'}`}>
                            {step.step_name}
                        </span>
                    </div>

                    {/* Meta info */}
                    <div className="flex items-center gap-2 mt-1">
                        <span className={`text-xs px-1.5 py-0.5 rounded ${config.bgColor} ${config.textColor}`}>
                            {config.label}
                        </span>
                        {(commentCount > 0 || attachmentCount > 0) && (
                            <span className="flex items-center gap-1.5 text-xs text-slate-400">
                                {commentCount > 0 && (
                                    <span className="flex items-center gap-0.5">
                                        <svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
                                        </svg>
                                        {commentCount}
                                    </span>
                                )}
                                {attachmentCount > 0 && (
                                    <span className="flex items-center gap-0.5">
                                        <svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13" />
                                        </svg>
                                        {attachmentCount}
                                    </span>
                                )}
                            </span>
                        )}
                    </div>
                </div>

                {/* Chevron */}
                <svg
                    className={`w-4 h-4 flex-shrink-0 transition-colors ${isSelected ? 'text-brand-500' : 'text-slate-300'}`}
                    fill="none"
                    stroke="currentColor"
                    viewBox="0 0 24 24"
                >
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
                </svg>
            </div>
        </button>
    );
}

// Inline status dropdown
function StatusDropdown({ currentStatus, onStatusChange, disabled, isUpdating }) {
    const [isOpen, setIsOpen] = React.useState(false);
    const dropdownRef = React.useRef(null);
    const config = getStatusConfig(currentStatus);

    // Close dropdown when clicking outside
    React.useEffect(() => {
        const handleClickOutside = (event) => {
            if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
                setIsOpen(false);
            }
        };
        document.addEventListener('mousedown', handleClickOutside);
        return () => document.removeEventListener('mousedown', handleClickOutside);
    }, []);

    const handleStatusSelect = (newStatus) => {
        if (newStatus === currentStatus) {
            setIsOpen(false);
            return;
        }
        // Immediately change status without notes dialog
        onStatusChange(newStatus, null);
        setIsOpen(false);
    };

    if (disabled) {
        return (
            <span className={`inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-sm font-medium ${config.bgColor} ${config.textColor}`}>
                <span className={config.iconColor}>{StatusIcons[currentStatus]}</span>
                {config.label}
            </span>
        );
    }

    return (
        <div className="relative" ref={dropdownRef}>
            <button
                onClick={() => setIsOpen(!isOpen)}
                disabled={isUpdating}
                className={`inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-sm font-medium transition-all ${config.bgColor} ${config.textColor} hover:opacity-80`}
            >
                {isUpdating ? (
                    <Spinner size="xs" />
                ) : (
                    <span className={config.iconColor}>{StatusIcons[currentStatus]}</span>
                )}
                {config.label}
                <svg className={`w-4 h-4 transition-transform ${isOpen ? 'rotate-180' : ''}`} fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
                </svg>
            </button>

            {isOpen && (
                <div className="absolute right-0 top-full mt-2 w-56 bg-white rounded-xl shadow-lg border border-slate-200 z-20 overflow-hidden">
                    <div className="p-2">
                        {statusOptions.map(opt => {
                            const optConfig = getStatusConfig(opt.value);
                            const isSelected = opt.value === currentStatus;
                            return (
                                <button
                                    key={opt.value}
                                    onClick={() => handleStatusSelect(opt.value)}
                                    className={`w-full flex items-center gap-2 px-3 py-2 rounded-lg text-left transition-colors ${
                                        isSelected ? 'bg-slate-100' : 'hover:bg-slate-50'
                                    }`}
                                >
                                    <span className={optConfig.iconColor}>{StatusIcons[opt.value]}</span>
                                    <span className="text-sm font-medium text-slate-700">{opt.label}</span>
                                    {isSelected && (
                                        <svg className="w-4 h-4 ml-auto text-brand-500" fill="currentColor" viewBox="0 0 20 20">
                                            <path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
                                        </svg>
                                    )}
                                </button>
                            );
                        })}
                    </div>
                </div>
            )}
        </div>
    );
}

// Attachment display component
function AttachmentItem({ attachment, currentUser, formatFileSize, formatRelativeTime, getFileIcon, onDownload, onDelete }) {
    const canDelete = attachment.uploaded_by === currentUser?.id || currentUser?.role === 'admin';

    return (
        <div className="flex items-center justify-between p-2 rounded-lg hover:bg-slate-50 group transition-colors">
            <div className="flex items-center gap-2 min-w-0 flex-1">
                <span className="text-lg flex-shrink-0">{getFileIcon(attachment.content_type)}</span>
                <div className="min-w-0">
                    <button
                        onClick={() => onDownload(attachment)}
                        className="text-sm font-medium text-brand-600 hover:text-brand-700 hover:underline truncate block max-w-[200px]"
                        title={attachment.original_filename}
                    >
                        {attachment.original_filename}
                    </button>
                    <div className="text-xs text-slate-400">
                        {formatFileSize(attachment.file_size)} • {formatRelativeTime(attachment.uploaded_at)}
                    </div>
                </div>
            </div>
            <div className="flex items-center gap-1 flex-shrink-0 opacity-0 group-hover:opacity-100 transition-opacity">
                <button
                    onClick={() => onDownload(attachment)}
                    className="p-1 text-slate-400 hover:text-brand-500 transition-colors"
                    title="Scarica"
                >
                    <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
                    </svg>
                </button>
                {canDelete && (
                    <button
                        onClick={() => onDelete(attachment.id, attachment.original_filename)}
                        className="p-1 text-slate-400 hover:text-red-500 transition-colors"
                        title="Elimina"
                    >
                        <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
                        </svg>
                    </button>
                )}
            </div>
        </div>
    );
}

// Comment display component with attachments and reactions
function CommentItem({
    comment, step, projectId, currentUser,
    formatRelativeTime, formatFileSize, getFileIcon,
    uploadingAttachment, onDeleteComment, onUploadAttachment,
    onDownloadAttachment, onDeleteAttachment
}) {
    const toast = useToast();
    const [showAttachUpload, setShowAttachUpload] = React.useState(false);
    const [showEmojiPicker, setShowEmojiPicker] = React.useState(false);
    const [reactions, setReactions] = React.useState(comment.reactions || {});
    const [togglingReaction, setTogglingReaction] = React.useState(false);
    const canDelete = comment.created_by === currentUser?.id || currentUser?.role === 'admin';
    const commentAttachments = comment.attachments || [];

    React.useEffect(() => {
        loadReactions();
    }, [comment.id]);

    const loadReactions = async () => {
        try {
            const data = await ApiUtils.getCommentReactions(projectId, step.id, comment.id);
            setReactions(data.reactions || {});
        } catch (err) {
            // Silently fail - reactions are optional
        }
    };

    const handleToggleReaction = async (emoji) => {
        if (togglingReaction) return;
        setTogglingReaction(true);
        setShowEmojiPicker(false);

        try {
            const result = await ApiUtils.toggleCommentReaction(projectId, step.id, comment.id, emoji);
            setReactions(prev => {
                const newReactions = { ...prev };
                const currentUserId = currentUser?.id;

                if (result.action === 'added') {
                    if (!newReactions[emoji]) {
                        newReactions[emoji] = [];
                    }
                    if (!newReactions[emoji].some(u => u.user_id === currentUserId)) {
                        newReactions[emoji].push({
                            user_id: currentUserId,
                            user_name: currentUser?.full_name || currentUser?.email,
                        });
                    }
                } else {
                    if (newReactions[emoji]) {
                        newReactions[emoji] = newReactions[emoji].filter(u => u.user_id !== currentUserId);
                        if (newReactions[emoji].length === 0) {
                            delete newReactions[emoji];
                        }
                    }
                }
                return newReactions;
            });
        } catch (err) {
            toast('Errore nella reazione: ' + err.message, 'error');
        } finally {
            setTogglingReaction(false);
        }
    };

    const hasUserReacted = (emoji) => {
        return reactions[emoji]?.some(u => u.user_id === currentUser?.id);
    };

    const getReactionTooltip = (emoji) => {
        const users = reactions[emoji] || [];
        if (users.length === 0) return '';
        if (users.length <= 3) {
            return users.map(u => u.user_name || 'Utente').join(', ');
        }
        return `${users.slice(0, 2).map(u => u.user_name || 'Utente').join(', ')} e altri ${users.length - 2}`;
    };

    const avatarUrl = comment.created_by_avatar ? window.ApiUsers?.getAvatarUrl(comment.created_by_avatar) : null;

    return (
        <div id={`step-comment-${comment.id}`} className="group transition-all duration-300">
            <div className="flex gap-3">
                {/* Avatar */}
                {avatarUrl ? (
                    <img
                        src={avatarUrl}
                        alt={comment.created_by_name}
                        className="w-8 h-8 rounded-full object-cover flex-shrink-0"
                    />
                ) : (
                    <div className="w-8 h-8 bg-brand-100 rounded-full flex items-center justify-center text-brand-600 text-xs font-semibold flex-shrink-0">
                        {comment.created_by_name?.charAt(0).toUpperCase() || '?'}
                    </div>
                )}

                {/* Content */}
                <div className="flex-1 min-w-0">
                    <div className="flex items-center gap-2">
                        <span className="text-sm font-medium text-slate-800">
                            {comment.created_by_name || 'Utente'}
                        </span>
                        <span className="text-xs text-slate-400">
                            {formatRelativeTime(comment.created_at)}
                        </span>

                        {/* Actions - show on hover */}
                        <div className="ml-auto flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
                            <div className="relative">
                                <button
                                    onClick={() => setShowEmojiPicker(!showEmojiPicker)}
                                    className="p-1 text-slate-300 hover:text-slate-500 transition-colors"
                                    title="Aggiungi reazione"
                                >
                                    <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M14.828 14.828a4 4 0 01-5.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                                    </svg>
                                </button>
                                {showEmojiPicker && (
                                    <div className="absolute right-0 top-7 z-20 bg-white rounded-lg shadow-lg border border-slate-200 p-1.5 flex gap-0.5">
                                        {REACTION_EMOJIS.map(emoji => (
                                            <button
                                                key={emoji}
                                                onClick={() => handleToggleReaction(emoji)}
                                                disabled={togglingReaction}
                                                className={`p-1 text-base hover:bg-slate-100 rounded transition-colors ${
                                                    hasUserReacted(emoji) ? 'bg-brand-50' : ''
                                                }`}
                                            >
                                                {emoji}
                                            </button>
                                        ))}
                                    </div>
                                )}
                            </div>
                            <button
                                onClick={() => setShowAttachUpload(!showAttachUpload)}
                                className="p-1 text-slate-300 hover:text-slate-500 transition-colors"
                                title="Aggiungi allegato"
                            >
                                <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13" />
                                </svg>
                            </button>
                            {canDelete && (
                                <button
                                    onClick={() => onDeleteComment(step.id, comment.id)}
                                    className="p-1 text-slate-300 hover:text-red-500 transition-colors"
                                    title="Elimina"
                                >
                                    <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
                                    </svg>
                                </button>
                            )}
                        </div>
                    </div>

                    <p className="text-sm text-slate-600 mt-1">
                        <MentionText text={comment.content} />
                    </p>

                    {/* Reactions */}
                    {Object.keys(reactions).length > 0 && (
                        <div className="mt-2 flex flex-wrap gap-1">
                            {Object.entries(reactions).map(([emoji, users]) => (
                                <button
                                    key={emoji}
                                    onClick={() => handleToggleReaction(emoji)}
                                    disabled={togglingReaction}
                                    className={`inline-flex items-center gap-1 px-1.5 py-0.5 rounded-full text-xs border transition-colors ${
                                        hasUserReacted(emoji)
                                            ? 'bg-brand-50 border-brand-200 text-brand-700'
                                            : 'bg-slate-50 border-slate-200 text-slate-600 hover:bg-slate-100'
                                    }`}
                                    title={getReactionTooltip(emoji)}
                                >
                                    <span>{emoji}</span>
                                    <span className="font-medium">{users.length}</span>
                                </button>
                            ))}
                        </div>
                    )}

                    {/* Comment Attachments */}
                    {commentAttachments.length > 0 && (
                        <div className="mt-2 space-y-1">
                            {commentAttachments.map(att => (
                                <div key={att.id} className="inline-flex items-center gap-1.5 text-xs bg-slate-100 rounded px-2 py-1 mr-2">
                                    <span>{getFileIcon(att.content_type)}</span>
                                    <button
                                        onClick={() => onDownloadAttachment(att)}
                                        className="text-brand-600 hover:underline truncate max-w-[150px]"
                                    >
                                        {att.original_filename}
                                    </button>
                                    {(att.uploaded_by === currentUser?.id || currentUser?.role === 'admin') && (
                                        <button
                                            onClick={() => onDeleteAttachment(att.id, att.original_filename)}
                                            className="text-slate-400 hover:text-red-500 ml-1"
                                        >
                                            ✕
                                        </button>
                                    )}
                                </div>
                            ))}
                        </div>
                    )}

                    {/* Upload attachment */}
                    {showAttachUpload && (
                        <div className="mt-2">
                            <label className="cursor-pointer inline-flex items-center gap-1.5 px-2 py-1 bg-slate-100 border border-slate-200 rounded text-xs text-slate-600 hover:bg-slate-200 transition-colors">
                                <input
                                    type="file"
                                    className="hidden"
                                    onChange={(e) => {
                                        if (e.target.files?.[0]) {
                                            onUploadAttachment(step.id, comment.id, e.target.files[0]);
                                            setShowAttachUpload(false);
                                        }
                                    }}
                                    disabled={uploadingAttachment[`comment-${comment.id}`]}
                                />
                                {uploadingAttachment[`comment-${comment.id}`] ? (
                                    <Spinner size="xs" />
                                ) : (
                                    <>Seleziona file</>
                                )}
                            </label>
                        </div>
                    )}
                </div>
            </div>
        </div>
    );
}

// Step detail panel
function StepDetailPanel({
    step, projectId, currentUser,
    canChangeStatus, isUpdating,
    onStatusChange, newComment, setNewComment,
    addingComment, onAddComment,
    uploadingAttachment, onUploadAttachment,
    onDeleteComment, onDownloadAttachment, onDeleteAttachment,
    onUploadCommentAttachment, formatRelativeTime, formatFileSize, formatDate, getFileIcon
}) {
    const config = getStatusConfig(step.status);
    const stepAttachments = step.attachments || [];

    return (
        <div className="h-full flex flex-col bg-white rounded-xl border border-slate-200 overflow-hidden animate-fade-in">
            {/* Header */}
            <div className="flex-shrink-0 p-4 border-b border-slate-100">
                <div className="flex items-start justify-between gap-3">
                    <div>
                        <h3 className="text-base font-semibold text-slate-800 mb-1">{step.step_name}</h3>
                        {step.history && step.history.length > 0 && (
                            <p className="text-xs text-slate-500">
                                Aggiornato da <span className="font-medium">{step.history[0].changed_by_name || 'Utente'}</span>
                                {' '}{formatRelativeTime(step.history[0].changed_at)}
                            </p>
                        )}
                    </div>

                    <StatusDropdown
                        currentStatus={step.status}
                        onStatusChange={(newStatus, notes) => onStatusChange(step, newStatus, notes)}
                        disabled={!canChangeStatus}
                        isUpdating={isUpdating}
                    />
                </div>
            </div>

            {/* Content - scrollable */}
            <div className="flex-1 overflow-y-auto p-4 space-y-4">
                {/* Notes */}
                {step.notes && (
                    <div className="bg-slate-50 rounded-lg p-3">
                        <h4 className="text-xs font-semibold text-slate-500 uppercase mb-1.5">Note</h4>
                        <p className="text-sm text-slate-700"><MentionText text={step.notes} /></p>
                    </div>
                )}

                {/* Attachments */}
                <div>
                    <div className="flex items-center justify-between mb-2">
                        <h4 className="text-xs font-semibold text-slate-500 uppercase flex items-center gap-1.5">
                            <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13" />
                            </svg>
                            Allegati
                            {stepAttachments.length > 0 && (
                                <span className="text-slate-400 font-normal">({stepAttachments.length})</span>
                            )}
                        </h4>
                        <label className="cursor-pointer">
                            <input
                                type="file"
                                className="hidden"
                                onChange={(e) => {
                                    if (e.target.files?.[0]) {
                                        onUploadAttachment(step.id, e.target.files[0]);
                                    }
                                }}
                                disabled={uploadingAttachment[`step-${step.id}`]}
                            />
                            <span className="flex items-center gap-1 px-2 py-1 text-xs font-medium text-brand-600 hover:text-brand-700 hover:bg-brand-50 rounded transition-colors">
                                {uploadingAttachment[`step-${step.id}`] ? (
                                    <Spinner size="xs" />
                                ) : (
                                    <>
                                        <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 4v16m8-8H4" />
                                        </svg>
                                        Carica
                                    </>
                                )}
                            </span>
                        </label>
                    </div>

                    {stepAttachments.length > 0 ? (
                        <div className="space-y-1">
                            {stepAttachments.map(att => (
                                <AttachmentItem
                                    key={att.id}
                                    attachment={att}
                                    currentUser={currentUser}
                                    formatFileSize={formatFileSize}
                                    formatRelativeTime={formatRelativeTime}
                                    getFileIcon={getFileIcon}
                                    onDownload={onDownloadAttachment}
                                    onDelete={onDeleteAttachment}
                                />
                            ))}
                        </div>
                    ) : (
                        <p className="text-sm text-slate-400 text-center py-3">Nessun allegato</p>
                    )}
                </div>

                {/* Comments */}
                <div>
                    <h4 className="text-xs font-semibold text-slate-500 uppercase flex items-center gap-1.5 mb-3">
                        <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
                        </svg>
                        Conversazione
                        {step.comments && step.comments.length > 0 && (
                            <span className="text-slate-400 font-normal">({step.comments.length})</span>
                        )}
                    </h4>

                    {step.comments && step.comments.length > 0 ? (
                        <div className="space-y-4">
                            {step.comments.map(comment => (
                                <CommentItem
                                    key={comment.id}
                                    comment={comment}
                                    step={step}
                                    projectId={projectId}
                                    currentUser={currentUser}
                                    formatRelativeTime={formatRelativeTime}
                                    formatFileSize={formatFileSize}
                                    getFileIcon={getFileIcon}
                                    uploadingAttachment={uploadingAttachment}
                                    onDeleteComment={onDeleteComment}
                                    onUploadAttachment={onUploadCommentAttachment}
                                    onDownloadAttachment={onDownloadAttachment}
                                    onDeleteAttachment={onDeleteAttachment}
                                />
                            ))}
                        </div>
                    ) : (
                        <p className="text-sm text-slate-400 text-center py-3">Nessun commento. Inizia la conversazione!</p>
                    )}
                </div>
            </div>

            {/* Comment input - fixed at bottom */}
            <div className="flex-shrink-0 p-3 border-t border-slate-100 bg-slate-50">
                <div className="flex items-center gap-2">
                    <div className="flex-1">
                        <MentionInput
                            value={newComment[step.id] || ''}
                            onChange={(val) => setNewComment(prev => ({ ...prev, [step.id]: val }))}
                            placeholder="Scrivi un commento..."
                            rows={1}
                            onKeyDown={(e) => {
                                if (e.key === 'Enter' && !e.shiftKey) {
                                    e.preventDefault();
                                    onAddComment(step.id);
                                }
                            }}
                        />
                    </div>
                    <button
                        onClick={() => onAddComment(step.id)}
                        disabled={addingComment[step.id] || !newComment[step.id]?.trim()}
                        className="flex-shrink-0 w-8 h-8 flex items-center justify-center bg-brand-500 text-white rounded-lg hover:bg-brand-600 transition-colors disabled:opacity-40 disabled:cursor-not-allowed"
                        title="Invia"
                    >
                        {addingComment[step.id] ? <Spinner size="xs" /> : (
                            <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8" />
                            </svg>
                        )}
                    </button>
                </div>
            </div>

            {/* Footer - timestamps */}
            <div className="flex-shrink-0 px-4 py-2 border-t border-slate-100 bg-slate-50/50">
                <div className="flex gap-4 text-xs text-slate-400">
                    <span>Creato: {formatDate(step.created_at)}</span>
                    <span>Aggiornato: {formatDate(step.updated_at)}</span>
                </div>
            </div>
        </div>
    );
}

// Main ProjectTimeline component
function ProjectTimeline({ projectId, canEdit = false, isAssigned = false, isCancelled = false, onStepChange = null, focusCommentId = null, focusStepId = null, onFocusHandled = null }) {
    const { user: currentUser, isAdmin } = useAuth();
    const isWorkflowLocked = isCancelled;
    const canChangeStatus = canEdit && (isAdmin || isAssigned) && !isWorkflowLocked;
    const toast = useToast();

    const [timeline, setTimeline] = React.useState(null);
    const [loading, setLoading] = React.useState(true);
    const [selectedStepId, setSelectedStepId] = React.useState(null);
    const [updatingStep, setUpdatingStep] = React.useState(null);
    const [newComment, setNewComment] = React.useState({});
    const [addingComment, setAddingComment] = React.useState({});
    const [uploadingAttachment, setUploadingAttachment] = React.useState({});
    const [confirmDelete, setConfirmDelete] = React.useState(null);
    const [focusHandled, setFocusHandled] = React.useState(false);

    // Use shared formatters
    const formatDate = Formatters.formatDate;
    const formatRelativeTime = Formatters.formatRelativeTime;
    const formatFileSize = Formatters.formatFileSize;

    const getFileIcon = (contentType) => {
        if (contentType.startsWith('image/')) return '🖼️';
        if (contentType.includes('pdf')) return '📄';
        if (contentType.includes('word') || contentType.includes('document')) return '📝';
        if (contentType.includes('excel') || contentType.includes('spreadsheet')) return '📊';
        if (contentType.includes('zip') || contentType.includes('rar') || contentType.includes('7z')) return '📦';
        return '📎';
    };

    const loadTimeline = async () => {
        await new Promise(resolve => setTimeout(resolve, 100));

        try {
            const data = await ApiUtils.getProjectTimeline(projectId, true);
            const newTimeline = {
                ...data,
                steps: data.steps ? data.steps.map(s => ({
                    ...s,
                    _key: Date.now(),
                    history: s.history ? s.history.map(h => ({ ...h, _key: Date.now() })) : [],
                    comments: s.comments ? s.comments.map(c => ({ ...c, _key: Date.now() })) : [],
                    attachments: s.attachments ? s.attachments.map(a => ({ ...a, _key: Date.now() })) : [],
                })) : [],
                _refreshed: Date.now()
            };
            setTimeline(newTimeline);

            // Auto-select first incomplete step (or last if all complete)
            if (!selectedStepId && newTimeline.steps?.length > 0) {
                const firstIncomplete = newTimeline.steps.find(s => s.status !== 'completato');
                setSelectedStepId(firstIncomplete?.id || newTimeline.steps[newTimeline.steps.length - 1].id);
            }
        } catch (err) {
            toast('Errore nel caricamento timeline: ' + err.message, 'error');
        } finally {
            setLoading(false);
        }
    };

    React.useEffect(() => {
        if (projectId) {
            loadTimeline();
        }
    }, [projectId]);

    // Handle focus on specific comment
    React.useEffect(() => {
        if (focusCommentId && focusStepId && timeline && !loading && !focusHandled) {
            setSelectedStepId(focusStepId);

            setTimeout(() => {
                const commentElement = document.getElementById(`step-comment-${focusCommentId}`);
                if (commentElement) {
                    commentElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
                    commentElement.classList.add('ring-2', 'ring-brand-500', 'ring-offset-2', 'bg-brand-50', 'rounded-lg');
                    setTimeout(() => {
                        commentElement.classList.remove('ring-2', 'ring-brand-500', 'ring-offset-2', 'bg-brand-50', 'rounded-lg');
                        setFocusHandled(true);
                        if (onFocusHandled) onFocusHandled();
                    }, 3000);
                } else {
                    setFocusHandled(true);
                    if (onFocusHandled) onFocusHandled();
                }
            }, 300);
        }
    }, [focusCommentId, focusStepId, timeline, loading, focusHandled, onFocusHandled]);

    React.useEffect(() => {
        if (focusCommentId && focusStepId) {
            setFocusHandled(false);
        }
    }, [focusCommentId, focusStepId]);

    const handleStatusChange = async (step, newStatus, notes = null) => {
        setUpdatingStep(step.id);
        try {
            await ApiUtils.updateStepStatus(projectId, step.id, {
                status: newStatus,
                notes: notes
            });
            toast('Stato aggiornato con successo', 'success');
            await loadTimeline();
            if (onStepChange) {
                onStepChange(projectId);
            }
            window.dispatchEvent(new CustomEvent('project-step-updated', {
                detail: { projectId }
            }));
            localStorage.setItem('rosa_projects_need_refresh', Date.now().toString());
        } catch (err) {
            toast('Errore nell\'aggiornamento: ' + err.message, 'error');
        } finally {
            setUpdatingStep(null);
        }
    };

    const handleAddComment = async (stepId) => {
        const content = newComment[stepId];
        if (!content?.trim()) return;

        setAddingComment(prev => ({ ...prev, [stepId]: true }));
        try {
            await ApiUtils.addStepComment(projectId, stepId, content.trim());
            setNewComment(prev => ({ ...prev, [stepId]: '' }));
            await loadTimeline();
            toast('Commento aggiunto', 'success');
        } catch (err) {
            toast('Errore nell\'aggiunta commento: ' + err.message, 'error');
        } finally {
            setAddingComment(prev => ({ ...prev, [stepId]: false }));
        }
    };

    const handleDeleteComment = (stepId, commentId) => {
        setConfirmDelete({ type: 'comment', stepId, commentId });
    };

    const handleUploadStepAttachment = async (stepId, file) => {
        setUploadingAttachment(prev => ({ ...prev, [`step-${stepId}`]: true }));
        try {
            await ApiUtils.uploadStepAttachment(projectId, stepId, file);
            await loadTimeline();
            toast('Allegato caricato con successo', 'success');
        } catch (err) {
            toast('Errore nel caricamento: ' + err.message, 'error');
        } finally {
            setUploadingAttachment(prev => ({ ...prev, [`step-${stepId}`]: false }));
        }
    };

    const handleUploadCommentAttachment = async (stepId, commentId, file) => {
        setUploadingAttachment(prev => ({ ...prev, [`comment-${commentId}`]: true }));
        try {
            await ApiUtils.uploadCommentAttachment(projectId, stepId, commentId, file);
            await loadTimeline();
            toast('Allegato caricato con successo', 'success');
        } catch (err) {
            toast('Errore nel caricamento: ' + err.message, 'error');
        } finally {
            setUploadingAttachment(prev => ({ ...prev, [`comment-${commentId}`]: false }));
        }
    };

    const handleDeleteAttachment = (attachmentId, filename) => {
        setConfirmDelete({ type: 'attachment', attachmentId, filename });
    };

    const executeDelete = async () => {
        if (!confirmDelete) return;

        try {
            if (confirmDelete.type === 'comment') {
                await ApiUtils.deleteStepComment(projectId, confirmDelete.stepId, confirmDelete.commentId);
                toast('Commento eliminato', 'success');
            } else if (confirmDelete.type === 'attachment') {
                await ApiUtils.deleteAttachment(confirmDelete.attachmentId);
                toast('Allegato eliminato', 'success');
            }
            setConfirmDelete(null);
            await loadTimeline();
        } catch (err) {
            toast('Errore nell\'eliminazione: ' + err.message, 'error');
            setConfirmDelete(null);
        }
    };

    const handleDownloadAttachment = (attachment) => {
        const url = ApiUtils.downloadAttachment(attachment.id);
        window.open(url, '_blank');
    };

    // Keyboard navigation
    React.useEffect(() => {
        const handleKeyDown = (e) => {
            if (!timeline?.steps || document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA') {
                return;
            }

            const currentIndex = timeline.steps.findIndex(s => s.id === selectedStepId);

            if (e.key === 'ArrowUp' || e.key === 'ArrowLeft') {
                e.preventDefault();
                if (currentIndex > 0) {
                    setSelectedStepId(timeline.steps[currentIndex - 1].id);
                }
            } else if (e.key === 'ArrowDown' || e.key === 'ArrowRight') {
                e.preventDefault();
                if (currentIndex < timeline.steps.length - 1) {
                    setSelectedStepId(timeline.steps[currentIndex + 1].id);
                }
            }
        };

        window.addEventListener('keydown', handleKeyDown);
        return () => window.removeEventListener('keydown', handleKeyDown);
    }, [timeline, selectedStepId]);

    if (loading) {
        return (
            <div className="p-8 text-center">
                <Spinner size="lg" />
                <p className="text-slate-500 mt-4">Caricamento workflow...</p>
            </div>
        );
    }

    if (!timeline || !timeline.steps || timeline.steps.length === 0) {
        return (
            <div className="p-8 text-center text-slate-500">
                Nessuna timeline disponibile per questa pratica
            </div>
        );
    }

    const completedCount = timeline.steps.filter(s => s.status === 'completato').length;
    const totalSteps = timeline.steps.length;
    const progressPercent = Math.round((completedCount / totalSteps) * 100);
    const selectedStep = timeline.steps.find(s => s.id === selectedStepId);

    return (
        <div className="flex flex-col h-full">
            {/* Workflow Locked Warning */}
            {isWorkflowLocked && (
                <div className="flex-shrink-0 mb-4 bg-amber-50 border border-amber-200 rounded-lg p-2.5 text-center">
                    <span className="text-amber-700 text-sm font-medium flex items-center justify-center gap-2">
                        <svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
                            <path fillRule="evenodd" d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z" clipRule="evenodd" />
                        </svg>
                        Workflow bloccato - Pratica conclusa
                    </span>
                </div>
            )}

            {/* Progress bar - minimal */}
            <div className="flex-shrink-0 mb-4">
                <div className="flex items-center justify-between mb-1.5">
                    <span className="text-xs font-medium text-slate-500">Progresso</span>
                    <span className="text-xs font-medium text-slate-600">
                        {completedCount}/{totalSteps} ({progressPercent}%)
                    </span>
                </div>
                <div className="w-full bg-slate-100 rounded-full h-1.5 overflow-hidden">
                    <div
                        className="h-full bg-gradient-to-r from-brand-400 to-teal-500 transition-all duration-500 ease-out"
                        style={{ width: `${progressPercent}%` }}
                    />
                </div>
            </div>

            {/* Split panel layout */}
            <div className="flex-1 flex gap-4 min-h-0">
                {/* Step list - left panel */}
                <div className="w-72 flex-shrink-0 flex flex-col">
                    <div className="flex-1 overflow-y-auto space-y-1 pr-1">
                        {timeline.steps.map(step => (
                            <StepListItem
                                key={step.id}
                                step={step}
                                isSelected={step.id === selectedStepId}
                                onClick={() => setSelectedStepId(step.id)}
                                formatRelativeTime={formatRelativeTime}
                            />
                        ))}
                    </div>
                    <div className="flex-shrink-0 mt-2 pt-2 border-t border-slate-100">
                        <p className="text-xs text-slate-400 text-center">Usa ↑↓ per navigare</p>
                    </div>
                </div>

                {/* Detail panel - right */}
                <div className="flex-1 min-w-0">
                    {selectedStep ? (
                        <StepDetailPanel
                            key={selectedStep.id}
                            step={selectedStep}
                            projectId={projectId}
                            currentUser={currentUser}
                            canChangeStatus={canChangeStatus}
                            isUpdating={updatingStep === selectedStep.id}
                            onStatusChange={handleStatusChange}
                            newComment={newComment}
                            setNewComment={setNewComment}
                            addingComment={addingComment}
                            onAddComment={handleAddComment}
                            uploadingAttachment={uploadingAttachment}
                            onUploadAttachment={handleUploadStepAttachment}
                            onDeleteComment={handleDeleteComment}
                            onDownloadAttachment={handleDownloadAttachment}
                            onDeleteAttachment={handleDeleteAttachment}
                            onUploadCommentAttachment={handleUploadCommentAttachment}
                            formatRelativeTime={formatRelativeTime}
                            formatFileSize={formatFileSize}
                            formatDate={formatDate}
                            getFileIcon={getFileIcon}
                        />
                    ) : (
                        <div className="h-full flex items-center justify-center text-slate-400">
                            Seleziona uno step per vedere i dettagli
                        </div>
                    )}
                </div>
            </div>

            {/* Confirmation Modal */}
            {confirmDelete && (
                <ConfirmationModal
                    title={confirmDelete.type === 'comment' ? 'Elimina Commento' : 'Elimina Allegato'}
                    message={confirmDelete.type === 'comment'
                        ? 'Sei sicuro di voler eliminare questo commento?'
                        : `Sei sicuro di voler eliminare "${confirmDelete.filename || 'questo allegato'}"?`
                    }
                    confirmText="Elimina"
                    variant="danger"
                    onConfirm={executeDelete}
                    onCancel={() => setConfirmDelete(null)}
                />
            )}

            {/* CSS for animations */}
            <style>{`
                @keyframes fade-in {
                    from { opacity: 0; transform: translateX(10px); }
                    to { opacity: 1; transform: translateX(0); }
                }
                .animate-fade-in {
                    animation: fade-in 0.2s ease-out;
                }
            `}</style>
        </div>
    );
}

window.ProjectTimeline = ProjectTimeline;
