/**
 * File attachment node with React NodeView.
 * Supports click-to-delete and status indicators (uploading/done/error).
 */

import { Node, mergeAttributes } from '@tiptap/core';
import { ReactNodeViewRenderer, NodeViewWrapper } from '@tiptap/react';
import { FileText, X, Loader2 } from 'lucide-react';
import { cn } from '@/lib/utils';

const FileComponent = (props: { node: { attrs: Record<string, string> }; deleteNode: () => void }) => {
  const { node, deleteNode } = props;
  const { name, size, type, status, url } = node.attrs;

  const isImage = type?.startsWith('image/');
  const isUploading = status === 'uploading';
  const isError = status === 'error';

  const formatSize = (bytes: number) => {
    if (bytes < 1024) return `${bytes} B`;
    if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
    return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
  };

  return (
    <NodeViewWrapper className="inline-block mx-1 align-middle select-none">
      <span
        className={cn(
          'flex items-center gap-2 border rounded-lg p-1.5 pr-2 max-w-[220px] group transition-colors',
          isError
            ? 'bg-red-50 border-red-200'
            : isUploading
            ? 'bg-gray-50 border-gray-200'
            : 'bg-gray-50 border-gray-200 hover:bg-gray-100',
        )}
      >
        {isImage && url ? (
          <img src={url} alt={name} className="w-6 h-6 rounded object-cover shrink-0" />
        ) : (
          <FileText size={20} className="text-blue-500 shrink-0" />
        )}

        <span className="min-w-0 flex-1">
          <span className="block truncate text-sm font-medium text-gray-700" title={name}>
            {name}
          </span>
          {size && (
            <span className="text-[11px] text-gray-400">{formatSize(Number(size))}</span>
          )}
        </span>

        {isUploading ? (
          <Loader2 size={14} className="text-gray-400 animate-spin shrink-0" />
        ) : isError ? (
          <span className="text-[10px] text-red-500 font-medium shrink-0">Failed</span>
        ) : null}

        <button
          onClick={deleteNode}
          className="text-gray-400 hover:text-red-500 opacity-0 group-hover:opacity-100 transition-opacity shrink-0"
          title="Remove"
        >
          <X size={14} />
        </button>
      </span>
    </NodeViewWrapper>
  );
};

export const FileNode = Node.create({
  name: 'file',
  group: 'inline',
  inline: true,
  selectable: true,
  atom: true,

  addAttributes() {
    return {
      id: { default: null },
      name: { default: '' },
      url: { default: '' },
      size: { default: 0 },
      type: { default: '' },
      status: { default: 'done' },
    };
  },

  parseHTML() {
    return [{ tag: 'span[data-type="file"]' }];
  },

  renderHTML({ HTMLAttributes }) {
    return ['span', mergeAttributes(HTMLAttributes, { 'data-type': 'file' })];
  },

  addNodeView() {
    return ReactNodeViewRenderer(FileComponent);
  },
});
