// components/PropertyInspector.tsx

import React, { useState } from 'react';
import { Neo4jNode, Neo4jRelationship } from '../graphTypes/graphTypes';
import { formatPropertyValue, getNodeColor } from '../graphUtils/graphUtils';
import { Eye, GitBranch, Tag, Hash, ArrowRight, Copy, Plus, X, Save, Trash2 } from 'lucide-react';

interface PropertyInspectorProps {
  selectedNode: Neo4jNode | null;
  selectedRelationship: Neo4jRelationship | null;
  onClearSelection: () => void;
  onToggleAddNode?: () => void;
  isAddingNode?: boolean;
  onCreateNode?: (nodeData: CreateNodeData) => void;
  onDeleteNode?: (nodeId: string) => void;
  onUpdateNode?: (nodeId: string, updates: Partial<Neo4jNode>) => void;
}

interface CreateNodeData {
  labels: string[];
  properties: Record<string, any>;
}

interface NodeFormData {
  labels: string;
  properties: { key: string; value: string }[];
}

const PropertyInspector: React.FC<PropertyInspectorProps> = ({
  selectedNode,
  selectedRelationship,
  onClearSelection,
  onToggleAddNode,
  isAddingNode = false,
  onCreateNode,
  onDeleteNode,
  onUpdateNode,
}) => {
  const [showCreateForm, setShowCreateForm] = useState(false);
  const [editingNode, setEditingNode] = useState<string | null>(null);
  const [formData, setFormData] = useState<NodeFormData>({
    labels: '',
    properties: [{ key: '', value: '' }]
  });

  const copyToClipboard = (text: string) => {
    navigator.clipboard.writeText(text);
  };

  const handleCreateNode = () => {
    if (onToggleAddNode) {
      onToggleAddNode();
    }
    setShowCreateForm(true);
  };

  const handleCancelCreate = () => {
    if (onToggleAddNode) {
      onToggleAddNode();
    }
    setShowCreateForm(false);
    setFormData({
      labels: '',
      properties: [{ key: '', value: '' }]
    });
  };

  const handleSaveNode = () => {
    if (!onCreateNode) return;

    const labels = formData.labels
      .split(',')
      .map(l => l.trim())
      .filter(l => l.length > 0);

    const properties: Record<string, any> = {};
    formData.properties.forEach(prop => {
      if (prop.key.trim() && prop.value.trim()) {
        // Try to parse as number or boolean, otherwise keep as string
        let value: any = prop.value.trim();
        if (value === 'true') value = true;
        else if (value === 'false') value = false;
        else if (!isNaN(Number(value)) && value !== '') value = Number(value);
        
        properties[prop.key.trim()] = value;
      }
    });

    onCreateNode({ labels, properties });
    handleCancelCreate();
  };

  const handleDeleteNode = () => {
    if (selectedNode && onDeleteNode) {
      onDeleteNode(selectedNode.id);
      onClearSelection();
    }
  };

  const addPropertyField = () => {
    setFormData(prev => ({
      ...prev,
      properties: [...prev.properties, { key: '', value: '' }]
    }));
  };

  const removePropertyField = (index: number) => {
    setFormData(prev => ({
      ...prev,
      properties: prev.properties.filter((_, i) => i !== index)
    }));
  };

  const updatePropertyField = (index: number, field: 'key' | 'value', value: string) => {
    setFormData(prev => ({
      ...prev,
      properties: prev.properties.map((prop, i) => 
        i === index ? { ...prop, [field]: value } : prop
      )
    }));
  };

  const formatProperties = (properties: Record<string, any>) => {
    const entries = Object.entries(properties);
    if (entries.length === 0) {
      return (
        <div className="text-gray-500 italic text-sm py-4 text-center">
          No properties available
        </div>
      );
    }

    return entries.map(([key, value]) => (
      <div key={key} className="flex items-start justify-between py-2 px-3 hover:bg-gray-50 rounded-md group">
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2 mb-1">
            <span className="font-medium text-gray-700 text-sm">{key}</span>
            <button
              onClick={() => copyToClipboard(`${key}: ${formatPropertyValue(value)}`)}
              className="opacity-0 group-hover:opacity-100 transition-opacity"
            >
              <Copy className="w-3 h-3 text-gray-400 hover:text-gray-600" />
            </button>
          </div>
          <div className="text-gray-900 text-sm break-words">
            {formatPropertyValue(value)}
          </div>
        </div>
      </div>
    ));
  };

  const renderCreateNodeForm = () => (
    <div className="p-4">
      <div className="mb-6">
        <div className="flex items-center justify-between mb-4">
          <h4 className="text-lg font-semibold text-green-600">Create New Node</h4>
          <button
            onClick={handleCancelCreate}
            className="text-gray-400 hover:text-gray-600 transition-colors"
          >
            <X className="w-5 h-5" />
          </button>
        </div>

        {/* Labels Input */}
        <div className="mb-4">
          <label className="block text-sm font-medium text-gray-700 mb-2">
            Labels (comma separated)
          </label>
          <input
            type="text"
            value={formData.labels}
            onChange={(e) => setFormData(prev => ({ ...prev, labels: e.target.value }))}
            placeholder="e.g., Person, User"
            className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
          />
        </div>

        {/* Properties */}
        <div className="mb-4">
          <div className="flex items-center justify-between mb-2">
            <label className="block text-sm font-medium text-gray-700">Properties</label>
            <button
              onClick={addPropertyField}
              className="text-blue-600 hover:text-blue-700 text-sm font-medium"
            >
              + Add Property
            </button>
          </div>
          
          <div className="space-y-2">
            {formData.properties.map((prop, index) => (
              <div key={index} className="flex gap-2">
                <input
                  type="text"
                  value={prop.key}
                  onChange={(e) => updatePropertyField(index, 'key', e.target.value)}
                  placeholder="Property name"
                  className="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm"
                />
                <input
                  type="text"
                  value={prop.value}
                  onChange={(e) => updatePropertyField(index, 'value', e.target.value)}
                  placeholder="Property value"
                  className="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-sm"
                />
                {formData.properties.length > 1 && (
                  <button
                    onClick={() => removePropertyField(index)}
                    className="px-2 py-2 text-red-600 hover:text-red-700"
                  >
                    <X className="w-4 h-4" />
                  </button>
                )}
              </div>
            ))}
          </div>
        </div>

        <div className="flex gap-2">
          <button
            onClick={handleSaveNode}
            className="flex-1 bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-md font-medium transition-colors flex items-center justify-center gap-2"
          >
            <Save className="w-4 h-4" />
            Create Node
          </button>
          <button
            onClick={handleCancelCreate}
            className="px-4 py-2 border border-gray-300 text-gray-700 rounded-md font-medium hover:bg-gray-50 transition-colors"
          >
            Cancel
          </button>
        </div>
      </div>
    </div>
  );

  if (showCreateForm) {
    return (
      <div className="w-80 h-full bg-white rounded-lg overflow-hidden border border-gray-200 shadow-lg mb-4">
        <div className="p-4 border-b border-gray-200 bg-gray-50">
          <div className="flex items-center gap-2">
            <Plus className="w-5 h-5 text-green-600" />
            <h3 className="text-lg font-semibold text-gray-800">Add Node</h3>
          </div>
        </div>
        <div className="flex-1 overflow-y-auto">
          {renderCreateNodeForm()}
        </div>
      </div>
    );
  }

  if (!selectedNode && !selectedRelationship) {
    return (
      <div className="w-80 h-full bg-gray-50 rounded-lg overflow-hidden border border-gray-200 mb-4">
        <div className="p-4 border-b border-gray-200 bg-gray-50">
          <div className="flex items-center justify-between">
            <div className="flex items-center gap-2">
              <Eye className="w-5 h-5 text-gray-600" />
              <h3 className="text-lg font-semibold text-gray-800">Inspector</h3>
            </div>
            {onToggleAddNode && (
              <button
                onClick={handleCreateNode}
                className={`px-3 py-1 rounded-md font-medium text-sm transition-colors flex items-center gap-1 ${
                  isAddingNode 
                    ? 'bg-green-100 text-green-700 border border-green-300' 
                    : 'bg-blue-100 text-blue-700 hover:bg-blue-200 border border-blue-300'
                }`}
              >
                <Plus className="w-4 h-4" />
                {isAddingNode ? 'Cancel' : 'Add Node'}
              </button>
            )}
          </div>
        </div>
        <div className="flex-1 flex items-center justify-center p-8">
          <div className="text-center">
            <div className="w-16 h-16 mx-auto mb-4 bg-gray-100 rounded-full flex items-center justify-center">
              <Eye className="w-8 h-8 text-gray-400" />
            </div>
            <p className="text-gray-500 mb-2">No selection</p>
            <p className="text-sm text-gray-400">
              Click on a node or relationship to view details
            </p>
            {isAddingNode && (
              <p className="text-sm text-green-600 mt-2 font-medium">
                Click anywhere on the canvas to add a new node
              </p>
            )}
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="w-80 h-full bg-gray-50 rounded-lg overflow-hidden border border-gray-200 mb-4">
      <div className="p-4 border-b border-gray-200 bg-gray-50">
        <div className="flex items-center justify-between">
          <div className="flex items-center gap-2">
            <Eye className="w-5 h-5 text-gray-600" />
            <h3 className="text-lg font-semibold text-gray-800">Inspector</h3>
          </div>
          <div className="flex items-center gap-2">
            {onToggleAddNode && (
              <button
                onClick={handleCreateNode}
                className="px-2 py-1 rounded-md font-medium text-sm transition-colors flex items-center gap-1 bg-blue-100 text-blue-700 hover:bg-blue-200 border border-blue-300"
              >
                <Plus className="w-3 h-3" />
              </button>
            )}
            <button
              onClick={onClearSelection}
              className="text-gray-400 hover:text-gray-600 transition-colors"
            >
              <X className="w-4 h-4" />
            </button>
          </div>
        </div>
      </div>

      <div className="flex-1 overflow-y-auto">
        {selectedNode && (
          <div className="p-4">
            {/* Node Header */}
            <div className="mb-6">
              <div className="flex items-center justify-between mb-3">
                <div className="flex items-center gap-3">
                  <div 
                    className="w-6 h-6 rounded-full border-2 border-white shadow-sm"
                    style={{ backgroundColor: getNodeColor(selectedNode.labels) }}
                  />
                  <h4 className="text-lg font-semibold text-blue-600">Node</h4>
                </div>
                {onDeleteNode && (
                  <button
                    onClick={handleDeleteNode}
                    className="p-1 text-red-400 hover:text-red-600 transition-colors"
                    title="Delete node"
                  >
                    <Trash2 className="w-4 h-4" />
                  </button>
                )}
              </div>
              
              {/* Node ID */}
              <div className="mb-3">
                <div className="flex items-center gap-2 mb-1">
                  <Hash className="w-4 h-4 text-gray-500" />
                  <span className="font-medium text-gray-700 text-sm">ID</span>
                </div>
                <div className="ml-6 font-mono text-sm text-gray-900 bg-gray-50 px-2 py-1 rounded">
                  {selectedNode.id}
                </div>
              </div>

              {/* Node Labels */}
              <div className="mb-4">
                <div className="flex items-center gap-2 mb-2">
                  <Tag className="w-4 h-4 text-gray-500" />
                  <span className="font-medium text-gray-700 text-sm">Labels</span>
                </div>
                <div className="ml-6 flex flex-wrap gap-1">
                  {selectedNode.labels.map(label => (
                    <span 
                      key={label} 
                      className="px-2 py-1 text-xs font-medium rounded-full"
                      style={{ 
                        backgroundColor: getNodeColor([label]) + '20',
                        color: getNodeColor([label])
                      }}
                    >
                      {label}
                    </span>
                  ))}
                </div>
              </div>
            </div>

            {/* Properties */}
            <div>
              <div className="flex items-center gap-2 mb-3">
                <GitBranch className="w-4 h-4 text-gray-500" />
                <span className="font-medium text-gray-700">Properties</span>
              </div>
              <div className="bg-gray-50 rounded-lg border border-gray-200">
                {formatProperties(selectedNode.properties)}
              </div>
            </div>
          </div>
        )}

        {selectedRelationship && (
          <div className="p-4">
            {/* Relationship Header */}
            <div className="mb-6">
              <div className="flex items-center gap-3 mb-3">
                <ArrowRight className="w-6 h-6 text-green-600" />
                <h4 className="text-lg font-semibold text-green-600">Relationship</h4>
              </div>
              
              {/* Relationship ID */}
              <div className="mb-3">
                <div className="flex items-center gap-2 mb-1">
                  <Hash className="w-4 h-4 text-gray-500" />
                  <span className="font-medium text-gray-700 text-sm">ID</span>
                </div>
                <div className="ml-6 font-mono text-sm text-gray-900 bg-gray-50 px-2 py-1 rounded">
                  {selectedRelationship.id}
                </div>
              </div>

              {/* Relationship Type */}
              <div className="mb-3">
                <div className="flex items-center gap-2 mb-1">
                  <Tag className="w-4 h-4 text-gray-500" />
                  <span className="font-medium text-gray-700 text-sm">Type</span>
                </div>
                <div className="ml-6">
                  <span className="px-3 py-1 bg-green-100 text-green-800 rounded-full text-sm font-medium">
                    {selectedRelationship.type}
                  </span>
                </div>
              </div>

              {/* Relationship Direction */}
              <div className="mb-4">
                <div className="flex items-center gap-2 mb-2">
                  <ArrowRight className="w-4 h-4 text-gray-500" />
                  <span className="font-medium text-gray-700 text-sm">Direction</span>
                </div>
                <div className="ml-6 bg-gray-50 rounded-lg p-3 border border-gray-200">
                  <div className="flex items-center justify-between text-sm">
                    <span className="font-mono text-gray-700">
                      {selectedRelationship.startNodeId}
                    </span>
                    <ArrowRight className="w-4 h-4 text-gray-400" />
                    <span className="font-mono text-gray-700">
                      {selectedRelationship.endNodeId}
                    </span>
                  </div>
                </div>
              </div>
            </div>

            {/* Properties */}
            <div>
              <div className="flex items-center gap-2 mb-3">
                <GitBranch className="w-4 h-4 text-gray-500" />
                <span className="font-medium text-gray-700">Properties</span>
              </div>
              <div className="bg-gray-50 rounded-lg border border-gray-200">
                {formatProperties(selectedRelationship.properties)}
              </div>
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

export default PropertyInspector;