/**
 * MemoryManagerPanel Component
 * Enhanced memory management with categories, edit/delete, and API integration
 * OQI-007: LLM Strategy Agent - Memory Management UI
 */

import React, { useState, useMemo, useCallback } from 'react';
import {
  CircleStackIcon,
  PencilIcon,
  TrashIcon,
  PlusIcon,
  FolderIcon,
  LightBulbIcon,
  ChartBarIcon,
  ClockIcon,
  CheckIcon,
  XMarkIcon,
  MagnifyingGlassIcon,
  ArrowPathIcon,
  ExclamationTriangleIcon,
} from '@heroicons/react/24/outline';

// ============================================================================
// Types
// ============================================================================

export type MemoryCategory = 'preferences' | 'strategies' | 'history' | 'custom';

export interface MemoryItem {
  id: string;
  category: MemoryCategory;
  key: string;
  value: string;
  metadata?: Record<string, unknown>;
  createdAt: string;
  updatedAt: string;
  isPinned?: boolean;
}

export interface MemoryStats {
  totalItems: number;
  totalTokens: number;
  maxTokens: number;
  byCategory: Record<MemoryCategory, number>;
}

interface MemoryManagerPanelProps {
  memories: MemoryItem[];
  stats: MemoryStats;
  onAddMemory: (memory: Omit<MemoryItem, 'id' | 'createdAt' | 'updatedAt'>) => Promise<void>;
  onUpdateMemory: (id: string, updates: Partial<MemoryItem>) => Promise<void>;
  onDeleteMemory: (id: string) => Promise<void>;
  onClearCategory?: (category: MemoryCategory) => Promise<void>;
  onRefresh?: () => Promise<void>;
  isLoading?: boolean;
}

// ============================================================================
// Constants
// ============================================================================

const CATEGORY_INFO: Record<MemoryCategory, { label: string; icon: React.ElementType; color: string }> = {
  preferences: { label: 'Preferencias', icon: LightBulbIcon, color: 'text-amber-500 bg-amber-500/10' },
  strategies: { label: 'Estrategias', icon: ChartBarIcon, color: 'text-blue-500 bg-blue-500/10' },
  history: { label: 'Historial', icon: ClockIcon, color: 'text-purple-500 bg-purple-500/10' },
  custom: { label: 'Personalizado', icon: FolderIcon, color: 'text-gray-500 bg-gray-500/10' },
};

// ============================================================================
// Sub-Components
// ============================================================================

interface MemoryItemCardProps {
  memory: MemoryItem;
  onEdit: () => void;
  onDelete: () => void;
  isEditing: boolean;
  editValue: string;
  onEditChange: (value: string) => void;
  onSave: () => void;
  onCancel: () => void;
}

const MemoryItemCard: React.FC<MemoryItemCardProps> = ({
  memory,
  onEdit,
  onDelete,
  isEditing,
  editValue,
  onEditChange,
  onSave,
  onCancel,
}) => {
  const [confirmDelete, setConfirmDelete] = useState(false);
  const category = CATEGORY_INFO[memory.category];
  const CategoryIcon = category.icon;

  return (
    <div className="group p-3 bg-gray-50 dark:bg-gray-800 rounded-lg border border-gray-100 dark:border-gray-700 hover:border-gray-200 dark:hover:border-gray-600 transition-colors">
      <div className="flex items-start gap-3">
        <div className={`p-2 rounded-lg ${category.color}`}>
          <CategoryIcon className="w-4 h-4" />
        </div>
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2 mb-1">
            <span className="text-xs font-medium text-gray-500 uppercase">{memory.key}</span>
            {memory.isPinned && (
              <span className="px-1.5 py-0.5 text-xs bg-primary-100 dark:bg-primary-900/30 text-primary-600 dark:text-primary-400 rounded">
                Fijado
              </span>
            )}
          </div>
          {isEditing ? (
            <div className="space-y-2">
              <textarea
                value={editValue}
                onChange={(e) => onEditChange(e.target.value)}
                className="w-full px-3 py-2 text-sm bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-600 rounded-lg resize-none focus:outline-none focus:ring-2 focus:ring-primary-500"
                rows={3}
                autoFocus
              />
              <div className="flex justify-end gap-2">
                <button
                  onClick={onCancel}
                  className="px-3 py-1.5 text-xs text-gray-500 hover:text-gray-700 dark:hover:text-gray-300"
                >
                  Cancelar
                </button>
                <button
                  onClick={onSave}
                  className="px-3 py-1.5 text-xs bg-primary-500 text-white rounded-lg hover:bg-primary-600"
                >
                  Guardar
                </button>
              </div>
            </div>
          ) : (
            <p className="text-sm text-gray-700 dark:text-gray-300 whitespace-pre-wrap">{memory.value}</p>
          )}
          <p className="text-xs text-gray-400 mt-2">
            {new Date(memory.updatedAt).toLocaleDateString('es-ES', {
              day: 'numeric',
              month: 'short',
              hour: '2-digit',
              minute: '2-digit',
            })}
          </p>
        </div>
        {!isEditing && (
          <div className="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
            {!confirmDelete ? (
              <>
                <button
                  onClick={onEdit}
                  className="p-1.5 text-gray-400 hover:text-primary-500 hover:bg-primary-50 dark:hover:bg-primary-900/20 rounded-lg"
                  title="Editar"
                >
                  <PencilIcon className="w-4 h-4" />
                </button>
                <button
                  onClick={() => setConfirmDelete(true)}
                  className="p-1.5 text-gray-400 hover:text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-lg"
                  title="Eliminar"
                >
                  <TrashIcon className="w-4 h-4" />
                </button>
              </>
            ) : (
              <>
                <button
                  onClick={() => { onDelete(); setConfirmDelete(false); }}
                  className="px-2 py-1 text-xs bg-red-500 text-white rounded hover:bg-red-600"
                >
                  Confirmar
                </button>
                <button
                  onClick={() => setConfirmDelete(false)}
                  className="p-1 text-gray-400 hover:text-gray-600"
                >
                  <XMarkIcon className="w-4 h-4" />
                </button>
              </>
            )}
          </div>
        )}
      </div>
    </div>
  );
};

interface AddMemoryFormProps {
  onAdd: (memory: Omit<MemoryItem, 'id' | 'createdAt' | 'updatedAt'>) => void;
  onCancel: () => void;
}

const AddMemoryForm: React.FC<AddMemoryFormProps> = ({ onAdd, onCancel }) => {
  const [category, setCategory] = useState<MemoryCategory>('custom');
  const [key, setKey] = useState('');
  const [value, setValue] = useState('');

  const handleSubmit = () => {
    if (key.trim() && value.trim()) {
      onAdd({ category, key: key.trim(), value: value.trim() });
    }
  };

  return (
    <div className="p-4 bg-gray-50 dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 space-y-3">
      <div className="grid grid-cols-2 gap-3">
        <div>
          <label className="block text-xs font-medium text-gray-500 mb-1">Categoria</label>
          <select
            value={category}
            onChange={(e) => setCategory(e.target.value as MemoryCategory)}
            className="w-full px-3 py-2 text-sm bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-600 rounded-lg"
          >
            {Object.entries(CATEGORY_INFO).map(([key, info]) => (
              <option key={key} value={key}>{info.label}</option>
            ))}
          </select>
        </div>
        <div>
          <label className="block text-xs font-medium text-gray-500 mb-1">Clave</label>
          <input
            type="text"
            value={key}
            onChange={(e) => setKey(e.target.value)}
            placeholder="ej: risk_tolerance"
            className="w-full px-3 py-2 text-sm bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-600 rounded-lg"
          />
        </div>
      </div>
      <div>
        <label className="block text-xs font-medium text-gray-500 mb-1">Valor</label>
        <textarea
          value={value}
          onChange={(e) => setValue(e.target.value)}
          placeholder="Contenido de la memoria..."
          className="w-full px-3 py-2 text-sm bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-600 rounded-lg resize-none"
          rows={3}
        />
      </div>
      <div className="flex justify-end gap-2">
        <button onClick={onCancel} className="px-4 py-2 text-sm text-gray-500 hover:text-gray-700">
          Cancelar
        </button>
        <button
          onClick={handleSubmit}
          disabled={!key.trim() || !value.trim()}
          className="px-4 py-2 text-sm bg-primary-500 text-white rounded-lg hover:bg-primary-600 disabled:opacity-50"
        >
          Agregar Memoria
        </button>
      </div>
    </div>
  );
};

// ============================================================================
// Main Component
// ============================================================================

export const MemoryManagerPanel: React.FC<MemoryManagerPanelProps> = ({
  memories,
  stats,
  onAddMemory,
  onUpdateMemory,
  onDeleteMemory,
  onClearCategory,
  onRefresh,
  isLoading = false,
}) => {
  const [activeCategory, setActiveCategory] = useState<MemoryCategory | 'all'>('all');
  const [searchQuery, setSearchQuery] = useState('');
  const [showAddForm, setShowAddForm] = useState(false);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [editValue, setEditValue] = useState('');

  const filteredMemories = useMemo(() => {
    let filtered = memories;
    if (activeCategory !== 'all') {
      filtered = filtered.filter((m) => m.category === activeCategory);
    }
    if (searchQuery.trim()) {
      const query = searchQuery.toLowerCase();
      filtered = filtered.filter(
        (m) => m.key.toLowerCase().includes(query) || m.value.toLowerCase().includes(query)
      );
    }
    return filtered.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
  }, [memories, activeCategory, searchQuery]);

  const handleAdd = useCallback(async (memory: Omit<MemoryItem, 'id' | 'createdAt' | 'updatedAt'>) => {
    await onAddMemory(memory);
    setShowAddForm(false);
  }, [onAddMemory]);

  const handleEdit = useCallback((memory: MemoryItem) => {
    setEditingId(memory.id);
    setEditValue(memory.value);
  }, []);

  const handleSave = useCallback(async (id: string) => {
    await onUpdateMemory(id, { value: editValue });
    setEditingId(null);
    setEditValue('');
  }, [editValue, onUpdateMemory]);

  const usagePercent = (stats.totalTokens / stats.maxTokens) * 100;

  return (
    <div className="bg-white dark:bg-gray-900 rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden">
      {/* Header */}
      <div className="p-4 border-b border-gray-200 dark:border-gray-700">
        <div className="flex items-center justify-between mb-3">
          <div className="flex items-center gap-2">
            <CircleStackIcon className="w-5 h-5 text-primary-500" />
            <h3 className="font-semibold text-gray-900 dark:text-white">Memoria del Agente</h3>
          </div>
          <div className="flex items-center gap-2">
            {onRefresh && (
              <button
                onClick={onRefresh}
                disabled={isLoading}
                className="p-2 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg"
              >
                <ArrowPathIcon className={`w-4 h-4 ${isLoading ? 'animate-spin' : ''}`} />
              </button>
            )}
            <button
              onClick={() => setShowAddForm(!showAddForm)}
              className="flex items-center gap-1.5 px-3 py-1.5 text-sm bg-primary-500 text-white rounded-lg hover:bg-primary-600"
            >
              <PlusIcon className="w-4 h-4" />
              Agregar
            </button>
          </div>
        </div>

        {/* Usage Bar */}
        <div className="mb-3">
          <div className="flex items-center justify-between text-xs mb-1">
            <span className="text-gray-500">{stats.totalItems} memorias</span>
            <span className={usagePercent > 80 ? 'text-red-500' : 'text-gray-500'}>
              {stats.totalTokens.toLocaleString()} / {stats.maxTokens.toLocaleString()} tokens
            </span>
          </div>
          <div className="h-2 bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden">
            <div
              className={`h-full transition-all ${usagePercent > 80 ? 'bg-red-500' : usagePercent > 60 ? 'bg-yellow-500' : 'bg-emerald-500'}`}
              style={{ width: `${Math.min(usagePercent, 100)}%` }}
            />
          </div>
          {usagePercent > 80 && (
            <div className="mt-2 p-2 bg-yellow-50 dark:bg-yellow-900/20 rounded-lg flex items-center gap-2 text-xs text-yellow-600 dark:text-yellow-400">
              <ExclamationTriangleIcon className="w-4 h-4" />
              <span>Memoria casi llena. Considera eliminar memorias antiguas.</span>
            </div>
          )}
        </div>

        {/* Category Stats */}
        <div className="grid grid-cols-4 gap-2">
          {Object.entries(CATEGORY_INFO).map(([key, info]) => {
            const Icon = info.icon;
            const count = stats.byCategory[key as MemoryCategory] || 0;
            return (
              <button
                key={key}
                onClick={() => setActiveCategory(activeCategory === key ? 'all' : key as MemoryCategory)}
                className={`p-2 rounded-lg border transition-colors ${
                  activeCategory === key
                    ? 'border-primary-500 bg-primary-50 dark:bg-primary-900/20'
                    : 'border-gray-100 dark:border-gray-700 hover:border-gray-200 dark:hover:border-gray-600'
                }`}
              >
                <Icon className={`w-4 h-4 mx-auto mb-1 ${info.color.split(' ')[0]}`} />
                <div className="text-lg font-bold text-gray-900 dark:text-white">{count}</div>
                <div className="text-xs text-gray-500 truncate">{info.label}</div>
              </button>
            );
          })}
        </div>
      </div>

      {/* Add Form */}
      {showAddForm && (
        <div className="p-4 border-b border-gray-200 dark:border-gray-700">
          <AddMemoryForm onAdd={handleAdd} onCancel={() => setShowAddForm(false)} />
        </div>
      )}

      {/* Search */}
      <div className="p-3 border-b border-gray-200 dark:border-gray-700">
        <div className="relative">
          <MagnifyingGlassIcon className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" />
          <input
            type="text"
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            placeholder="Buscar memorias..."
            className="w-full pl-9 pr-3 py-2 text-sm bg-gray-100 dark:bg-gray-800 border-0 rounded-lg focus:ring-2 focus:ring-primary-500"
          />
        </div>
      </div>

      {/* Memory List */}
      <div className="max-h-96 overflow-y-auto p-3 space-y-2">
        {filteredMemories.length === 0 ? (
          <div className="p-8 text-center">
            <CircleStackIcon className="w-12 h-12 mx-auto text-gray-300 dark:text-gray-600 mb-3" />
            <p className="text-gray-500 text-sm">
              {searchQuery ? 'No se encontraron memorias' : 'Sin memorias guardadas'}
            </p>
            <p className="text-gray-400 text-xs mt-1">
              Las memorias ayudan al agente a recordar tus preferencias
            </p>
          </div>
        ) : (
          filteredMemories.map((memory) => (
            <MemoryItemCard
              key={memory.id}
              memory={memory}
              onEdit={() => handleEdit(memory)}
              onDelete={() => onDeleteMemory(memory.id)}
              isEditing={editingId === memory.id}
              editValue={editValue}
              onEditChange={setEditValue}
              onSave={() => handleSave(memory.id)}
              onCancel={() => { setEditingId(null); setEditValue(''); }}
            />
          ))
        )}
      </div>

      {/* Clear Category Footer */}
      {activeCategory !== 'all' && filteredMemories.length > 0 && onClearCategory && (
        <div className="p-3 border-t border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/50">
          <button
            onClick={() => onClearCategory(activeCategory)}
            className="w-full flex items-center justify-center gap-2 px-4 py-2 text-sm text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-lg transition-colors"
          >
            <TrashIcon className="w-4 h-4" />
            Limpiar {CATEGORY_INFO[activeCategory].label} ({filteredMemories.length})
          </button>
        </div>
      )}
    </div>
  );
};

export default MemoryManagerPanel;
