import React, { useState, useMemo } from 'react';
import { format, formatDistance } from 'date-fns';

interface Change {
  id: string;
  userId: string;
  userName: string;
  userAvatar?: string;
  timestamp: Date;
  field: string;
  oldValue: any;
  newValue: any;
  type: 'create' | 'update' | 'delete';
  metadata?: Record<string, any>;
}

interface ChangeHistoryProps {
  changes: Change[];
  onRevert?: (changeId: string) => void;
  onCompare?: (changeId1: string, changeId2: string) => void;
  maxDisplay?: number;
  showDiff?: boolean;
  className?: string;
}

/**
 * Change History Component
 * Displays document change history with diff visualization
 */
export const ChangeHistory: React.FC<ChangeHistoryProps> = ({
  changes,
  onRevert,
  onCompare,
  maxDisplay = 50,
  showDiff = true,
  className = ''
}) => {
  const [expandedChanges, setExpandedChanges] = useState<Set<string>>(new Set());
  const [selectedChanges, setSelectedChanges] = useState<Set<string>>(new Set());
  const [filterField, setFilterField] = useState<string>('');
  const [filterUser, setFilterUser] = useState<string>('');

  // Filter changes
  const filteredChanges = useMemo(() => {
    let filtered = [...changes];
    
    if (filterField) {
      filtered = filtered.filter(c => c.field.includes(filterField));
    }
    
    if (filterUser) {
      filtered = filtered.filter(c => c.userName.toLowerCase().includes(filterUser.toLowerCase()));
    }
    
    return filtered.slice(0, maxDisplay);
  }, [changes, filterField, filterUser, maxDisplay]);

  // Group changes by time period
  const groupedChanges = useMemo(() => {
    const groups: Record<string, Change[]> = {};
    const now = new Date();
    
    filteredChanges.forEach(change => {
      const diff = now.getTime() - change.timestamp.getTime();
      let group: string;
      
      if (diff < 3600000) { // Less than 1 hour
        group = 'Last Hour';
      } else if (diff < 86400000) { // Less than 1 day
        group = 'Today';
      } else if (diff < 604800000) { // Less than 1 week
        group = 'This Week';
      } else {
        group = format(change.timestamp, 'MMMM yyyy');
      }
      
      if (!groups[group]) {
        groups[group] = [];
      }
      groups[group].push(change);
    });
    
    return groups;
  }, [filteredChanges]);

  // Toggle change expansion
  const toggleExpanded = (changeId: string) => {
    setExpandedChanges(prev => {
      const next = new Set(prev);
      if (next.has(changeId)) {
        next.delete(changeId);
      } else {
        next.add(changeId);
      }
      return next;
    });
  };

  // Handle change selection for comparison
  const toggleSelected = (changeId: string) => {
    setSelectedChanges(prev => {
      const next = new Set(prev);
      if (next.has(changeId)) {
        next.delete(changeId);
      } else {
        next.add(changeId);
      }
      
      // Auto-compare when 2 changes are selected
      if (next.size === 2 && onCompare) {
        const [id1, id2] = Array.from(next);
        onCompare(id1, id2);
      }
      
      return next;
    });
  };

  // Get change type icon
  const getChangeIcon = (type: Change['type']) => {
    switch (type) {
      case 'create':
        return '➕';
      case 'update':
        return '✏️';
      case 'delete':
        return '🗑️';
      default:
        return '📝';
    }
  };

  // Format field name
  const formatFieldName = (field: string) => {
    return field
      .replace(/([A-Z])/g, ' $1')
      .replace(/^./, str => str.toUpperCase())
      .trim();
  };

  // Render value diff
  const renderDiff = (oldValue: any, newValue: any) => {
    if (!showDiff) return null;
    
    const oldStr = typeof oldValue === 'object' ? JSON.stringify(oldValue, null, 2) : String(oldValue || '');
    const newStr = typeof newValue === 'object' ? JSON.stringify(newValue, null, 2) : String(newValue || '');
    
    // Simple diff visualization
    if (oldStr === newStr) return null;
    
    return (
      <div className="change-history__diff">
        {oldStr && (
          <div className="change-history__diff-old">
            <span className="change-history__diff-label">Old:</span>
            <pre>{oldStr}</pre>
          </div>
        )}
        {newStr && (
          <div className="change-history__diff-new">
            <span className="change-history__diff-label">New:</span>
            <pre>{newStr}</pre>
          </div>
        )}
      </div>
    );
  };

  // Render single change item
  const renderChange = (change: Change) => {
    const isExpanded = expandedChanges.has(change.id);
    const isSelected = selectedChanges.has(change.id);
    
    return (
      <div 
        key={change.id}
        className={`change-history__item ${isSelected ? 'selected' : ''}`}
      >
        <div className="change-history__item-header" onClick={() => toggleExpanded(change.id)}>
          <input
            type="checkbox"
            checked={isSelected}
            onChange={() => toggleSelected(change.id)}
            onClick={(e) => e.stopPropagation()}
            className="change-history__checkbox"
          />
          
          <div className="change-history__icon">
            {getChangeIcon(change.type)}
          </div>
          
          <div className="change-history__user">
            {change.userAvatar ? (
              <img src={change.userAvatar} alt={change.userName} />
            ) : (
              <div className="change-history__user-initial">
                {change.userName.charAt(0).toUpperCase()}
              </div>
            )}
          </div>
          
          <div className="change-history__info">
            <div className="change-history__summary">
              <strong>{change.userName}</strong> {change.type}d{' '}
              <span className="change-history__field">{formatFieldName(change.field)}</span>
            </div>
            <div className="change-history__time">
              {formatDistance(change.timestamp, new Date(), { addSuffix: true })}
            </div>
          </div>
          
          <div className="change-history__actions">
            {onRevert && (
              <button
                className="change-history__revert"
                onClick={(e) => {
                  e.stopPropagation();
                  onRevert(change.id);
                }}
                title="Revert this change"
              >
                ↩️
              </button>
            )}
            <button className="change-history__expand">
              {isExpanded ? '▼' : '▶'}
            </button>
          </div>
        </div>
        
        {isExpanded && (
          <div className="change-history__details">
            {renderDiff(change.oldValue, change.newValue)}
            {change.metadata && (
              <div className="change-history__metadata">
                <span className="change-history__metadata-label">Additional Info:</span>
                <pre>{JSON.stringify(change.metadata, null, 2)}</pre>
              </div>
            )}
          </div>
        )}
      </div>
    );
  };

  return (
    <div className={`change-history ${className}`}>
      <div className="change-history__header">
        <h3 className="change-history__title">Change History</h3>
        
        <div className="change-history__filters">
          <input
            type="text"
            placeholder="Filter by field..."
            value={filterField}
            onChange={(e) => setFilterField(e.target.value)}
            className="change-history__filter"
          />
          <input
            type="text"
            placeholder="Filter by user..."
            value={filterUser}
            onChange={(e) => setFilterUser(e.target.value)}
            className="change-history__filter"
          />
        </div>
        
        {selectedChanges.size > 0 && (
          <div className="change-history__selection">
            {selectedChanges.size} selected
            <button onClick={() => setSelectedChanges(new Set())}>Clear</button>
          </div>
        )}
      </div>
      
      <div className="change-history__content">
        {Object.entries(groupedChanges).map(([group, groupChanges]) => (
          <div key={group} className="change-history__group">
            <div className="change-history__group-header">
              {group} ({groupChanges.length})
            </div>
            <div className="change-history__group-items">
              {groupChanges.map(renderChange)}
            </div>
          </div>
        ))}
        
        {filteredChanges.length === 0 && (
          <div className="change-history__empty">
            No changes found
          </div>
        )}
      </div>
      
      <style jsx>{`
        .change-history {
          background: white;
          border: 1px solid #e0e0e0;
          border-radius: 8px;
          overflow: hidden;
        }
        
        .change-history__header {
          padding: 16px;
          border-bottom: 1px solid #e0e0e0;
          display: flex;
          align-items: center;
          justify-content: space-between;
          gap: 16px;
        }
        
        .change-history__title {
          margin: 0;
          font-size: 18px;
          font-weight: 600;
        }
        
        .change-history__filters {
          display: flex;
          gap: 8px;
          flex: 1;
          max-width: 400px;
        }
        
        .change-history__filter {
          flex: 1;
          padding: 6px 12px;
          border: 1px solid #ddd;
          border-radius: 4px;
          font-size: 14px;
        }
        
        .change-history__selection {
          display: flex;
          align-items: center;
          gap: 8px;
          font-size: 14px;
          color: #666;
        }
        
        .change-history__selection button {
          padding: 4px 8px;
          background: #f0f0f0;
          border: none;
          border-radius: 4px;
          cursor: pointer;
          font-size: 12px;
        }
        
        .change-history__content {
          max-height: 600px;
          overflow-y: auto;
        }
        
        .change-history__group {
          border-bottom: 1px solid #f0f0f0;
        }
        
        .change-history__group:last-child {
          border-bottom: none;
        }
        
        .change-history__group-header {
          padding: 12px 16px;
          background: #f8f8f8;
          font-size: 13px;
          font-weight: 600;
          color: #666;
          text-transform: uppercase;
          letter-spacing: 0.5px;
        }
        
        .change-history__item {
          border-bottom: 1px solid #f0f0f0;
          transition: background 0.2s ease;
        }
        
        .change-history__item:last-child {
          border-bottom: none;
        }
        
        .change-history__item.selected {
          background: #e8f5ff;
        }
        
        .change-history__item-header {
          padding: 12px 16px;
          display: flex;
          align-items: center;
          gap: 12px;
          cursor: pointer;
        }
        
        .change-history__item-header:hover {
          background: #f8f8f8;
        }
        
        .change-history__checkbox {
          cursor: pointer;
        }
        
        .change-history__icon {
          font-size: 16px;
        }
        
        .change-history__user {
          width: 28px;
          height: 28px;
          flex-shrink: 0;
        }
        
        .change-history__user img {
          width: 100%;
          height: 100%;
          border-radius: 50%;
          object-fit: cover;
        }
        
        .change-history__user-initial {
          width: 100%;
          height: 100%;
          border-radius: 50%;
          background: #4ECDC4;
          color: white;
          display: flex;
          align-items: center;
          justify-content: center;
          font-size: 12px;
          font-weight: bold;
        }
        
        .change-history__info {
          flex: 1;
        }
        
        .change-history__summary {
          font-size: 14px;
          color: #333;
        }
        
        .change-history__field {
          color: #4ECDC4;
          font-weight: 500;
        }
        
        .change-history__time {
          font-size: 12px;
          color: #999;
          margin-top: 2px;
        }
        
        .change-history__actions {
          display: flex;
          align-items: center;
          gap: 8px;
        }
        
        .change-history__revert,
        .change-history__expand {
          background: none;
          border: none;
          cursor: pointer;
          padding: 4px;
          font-size: 14px;
        }
        
        .change-history__details {
          padding: 0 16px 16px 56px;
          animation: slideDown 0.2s ease;
        }
        
        @keyframes slideDown {
          from {
            opacity: 0;
            transform: translateY(-8px);
          }
          to {
            opacity: 1;
            transform: translateY(0);
          }
        }
        
        .change-history__diff {
          margin-top: 8px;
          font-family: monospace;
          font-size: 12px;
        }
        
        .change-history__diff-old,
        .change-history__diff-new {
          margin: 8px 0;
          padding: 8px;
          border-radius: 4px;
        }
        
        .change-history__diff-old {
          background: #ffebee;
          border-left: 3px solid #f44336;
        }
        
        .change-history__diff-new {
          background: #e8f5e9;
          border-left: 3px solid #4caf50;
        }
        
        .change-history__diff-label {
          font-weight: bold;
          margin-right: 8px;
        }
        
        .change-history__diff pre {
          margin: 4px 0 0 0;
          white-space: pre-wrap;
          word-break: break-word;
        }
        
        .change-history__metadata {
          margin-top: 12px;
          padding: 8px;
          background: #f5f5f5;
          border-radius: 4px;
          font-size: 12px;
        }
        
        .change-history__metadata-label {
          font-weight: bold;
          display: block;
          margin-bottom: 4px;
        }
        
        .change-history__metadata pre {
          margin: 0;
          font-family: monospace;
        }
        
        .change-history__empty {
          padding: 32px;
          text-align: center;
          color: #999;
        }
      `}</style>
    </div>
  );
};