﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿
/* === Data Dictionary Management Page === */
/* global useToast, Icons, ConfirmModal */
function PageOperationDict() {
  const toast = useToast();
  const [categories, setCategories] = React.useState([]);
  const [selectedCategory, setSelectedCategory] = React.useState(null);
  const [items, setItems] = React.useState([]);
  const [categoryModalVisible, setCategoryModalVisible] = React.useState(false);
  const [itemModalVisible, setItemModalVisible] = React.useState(false);
  const [editingCategory, setEditingCategory] = React.useState(null);
  const [editingItem, setEditingItem] = React.useState(null);
  const [loading, setLoading] = React.useState(false);
  const [expandedNodes, setExpandedNodes] = React.useState(new Set());
  const [draggingNode, setDraggingNode] = React.useState(null);
  const [dropTarget, setDropTarget] = React.useState(null);
  const [confirmModalVisible, setConfirmModalVisible] = React.useState(false);
  const [confirmConfig, setConfirmConfig] = React.useState({ title: '', message: '', onConfirm: () => {} });
  const [sidebarCollapsed, setSidebarCollapsed] = React.useState(false);

  const fetchCategories = async function() {
    try {
      const data = await window.apiFetch('/api/dict/category/tree');
      if (Array.isArray(data)) {
        setCategories(data);
        // 默认展开根节点
        const newExpanded = new Set();
        function collectNodeIds(nodes) {
          nodes.forEach(node => {
            if (node.parent_id === 0) {
              newExpanded.add(node.id);
            }
            if (node.children && node.children.length > 0) {
              collectNodeIds(node.children);
            }
          });
        }
        collectNodeIds(data);
        setExpandedNodes(newExpanded);
      } else {
        console.error('API返回数据格式错误:', data);
        setCategories([]);
      }
    } catch (error) {
      console.error('获取分类失败:', error);
      setCategories([]);
    }
  };

  React.useEffect(function() {
    fetchCategories();
  }, []);

  const fetchItems = async function(categoryCode) {
    if (!categoryCode) return;
    try {
      setLoading(true);
      const data = await window.apiFetch('/api/dict/item/list?category_code=' + categoryCode);
      if (Array.isArray(data)) {
        setItems(data);
      } else {
        console.error('API返回数据格式错误:', data);
        setItems([]);
      }
    } catch (error) {
      console.error('获取字典项失败:', error);
      setItems([]);
    } finally {
      setLoading(false);
    }
  };

  React.useEffect(function() {
    if (selectedCategory) {
      fetchItems(selectedCategory.code);
    }
  }, [selectedCategory]);

  const toggleExpand = function(nodeId) {
    const newExpanded = new Set(expandedNodes);
    if (newExpanded.has(nodeId)) {
      newExpanded.delete(nodeId);
    } else {
      newExpanded.add(nodeId);
    }
    setExpandedNodes(newExpanded);
  };

  const handleAddCategory = function() {
    setEditingCategory({
      parent_id: selectedCategory ? selectedCategory.id : 0,
      code: '',
      name: '',
      importance: 'normal',
      sort: 1,
      status: 1,
      remark: ''
    });
    setCategoryModalVisible(true);
  };

  const handleEditCategory = function(category) {
    setEditingCategory(Object.assign({}, category));
    setCategoryModalVisible(true);
  };

  const handleSaveCategory = async function() {
    if (!editingCategory.code || !editingCategory.name) {
      toast.push('请填写编码和名称', 'warn');
      return;
    }
    try {
      if (editingCategory.id) {
        await window.apiFetch('/api/dict/category/' + editingCategory.id, {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(editingCategory)
        });
        toast.push('分类更新成功', 'success');
      } else {
        await window.apiFetch('/api/dict/category/', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(editingCategory)
        });
        toast.push('分类创建成功', 'success');
      }
      setCategoryModalVisible(false);
      setEditingCategory(null);
      fetchCategories();
    } catch (error) {
      console.error('保存分类失败:', error);
      toast.push('保存失败: ' + (error.detail || error.message || '未知错误'), 'error');
    }
  };

  const handleDeleteCategory = async function(category) {
    setConfirmConfig({
      title: '确认删除',
      message: '确定要删除分类"' + category.name + '"吗？',
      onConfirm: async () => {
        try {
          await window.apiFetch('/api/dict/category/' + category.id, { method: 'DELETE' });
          if (selectedCategory && selectedCategory.id === category.id) {
            setSelectedCategory(null);
          }
          toast.push('分类删除成功', 'success');
          fetchCategories();
        } catch (error) {
          console.error('删除分类失败:', error);
          toast.push('删除失败: ' + (error.detail || error.message || '未知错误'), 'error');
        }
      }
    });
    setConfirmModalVisible(true);
  };

  const handleAddItem = function() {
    setEditingItem({
      category_code: selectedCategory.code,
      label: '',
      value: '',
      parent_value: '',
      ref_category_code: '',
      sort: 1,
      status: 1,
      extra: '',
      remark: ''
    });
    setItemModalVisible(true);
  };

  const handleEditItem = function(item) {
    setEditingItem(Object.assign({}, item));
    setItemModalVisible(true);
  };

  const handleSaveItem = async function() {
    if (!editingItem.label || !editingItem.value) {
      toast.push('请填写显示名称和编码', 'warn');
      return;
    }
    try {
      var saveData = Object.assign({}, editingItem);
      if (saveData.extra && typeof saveData.extra === 'string') {
        try {
          saveData.extra = JSON.parse(saveData.extra);
        } catch (e) {
          saveData.extra = null;
        }
      }
      if (!saveData.extra || Object.keys(saveData.extra).length === 0) {
        saveData.extra = null;
      }
      if (!saveData.parent_value) saveData.parent_value = null;
      if (!saveData.ref_category_code) saveData.ref_category_code = null;

      if (editingItem.id) {
        await window.apiFetch('/api/dict/item/' + editingItem.id, {
          method: 'PUT',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(saveData)
        });
        toast.push('字典项更新成功', 'success');
      } else {
        await window.apiFetch('/api/dict/item/', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(saveData)
        });
        toast.push('字典项创建成功', 'success');
      }
      setItemModalVisible(false);
      setEditingItem(null);
      fetchItems(selectedCategory.code);
    } catch (error) {
      console.error('保存字典项失败:', error);
      toast.push('保存失败: ' + (error.detail || error.message || '未知错误'), 'error');
    }
  };

  const handleDeleteItem = async function(item) {
    setConfirmConfig({
      title: '确认删除',
      message: '确定要删除字典项"' + item.label + '"吗？',
      onConfirm: async () => {
        try {
          await window.apiFetch('/api/dict/item/' + item.id, { method: 'DELETE' });
          toast.push('字典项删除成功', 'success');
          fetchItems(selectedCategory.code);
        } catch (error) {
          console.error('删除字典项失败:', error);
          toast.push('删除失败: ' + (error.detail || error.message || '未知错误'), 'error');
        }
      }
    });
    setConfirmModalVisible(true);
  };

  const handleDragStart = function(e, node) {
    if (node.id === 'root') return;
    setDraggingNode(node);
    e.dataTransfer.effectAllowed = 'move';
    e.dataTransfer.setData('text/plain', JSON.stringify(node));
  };

  const handleDragOver = function(e, node) {
    if (!draggingNode || draggingNode.id === node.id) {
      e.preventDefault();
      return;
    }
    e.preventDefault();
    setDropTarget(node.id);
  };

  const handleDragLeave = function() {
    setDropTarget(null);
  };

  const handleDrop = async function(e, targetNode) {
    e.preventDefault();
    if (!draggingNode || draggingNode.id === targetNode.id) {
      setDropTarget(null);
      setDraggingNode(null);
      return;
    }
    try {
      await window.apiFetch('/api/dict/category/' + draggingNode.id, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          ...draggingNode,
          parent_id: targetNode.id
        })
      });
      toast.push('分类移动成功', 'success');
      fetchCategories();
    } catch (error) {
      console.error('移动分类失败:', error);
      toast.push('移动失败: ' + (error.detail || error.message || '未知错误'), 'error');
    }
    setDropTarget(null);
    setDraggingNode(null);
  };

  const handleDragEnd = function() {
    setDraggingNode(null);
    setDropTarget(null);
  };

  const renderTree = function(nodes, level) {
    if (!Array.isArray(nodes)) return [];
    level = level || 0;
    var elements = [];

    // 根目录节点
    if (level === 0) {
      var isRootActive = selectedCategory === null;
      var isRootDropTarget = dropTarget === 'root';
      elements.push(
        <div key="root">
          <div
            className={'tree-item ' + (isRootActive ? 'active' : '') + (isRootDropTarget ? ' drop-target' : '')}
            style={{ paddingLeft: '8px' }}
            onClick={() => setSelectedCategory(null)}
            onDragOver={(e) => {
              e.preventDefault();
              if (draggingNode) {
                setDropTarget('root');
              }
            }}
            onDragLeave={() => {
              if (dropTarget === 'root') {
                setDropTarget(null);
              }
            }}
            onDrop={async (e) => {
              e.preventDefault();
              if (!draggingNode) return;
              try {
                await window.apiFetch('/api/dict/category/' + draggingNode.id, {
                  method: 'PUT',
                  headers: { 'Content-Type': 'application/json' },
                  body: JSON.stringify({
                    ...draggingNode,
                    parent_id: 0
                  })
                });
                toast.push('分类移动成功', 'success');
                fetchCategories();
              } catch (error) {
                console.error('移动分类失败:', error);
                toast.push('移动失败: ' + (error.detail || error.message || '未知错误'), 'error');
              }
              setDropTarget(null);
              setDraggingNode(null);
            }}
          >
            <span className="tree-toggle" style={{ visibility: 'hidden' }}>
              ▸
            </span>
            <span className="tree-node-content">
              <span className="tree-icon">{Icons.home}</span>
              <span className="tree-label" title="根目录">根目录</span>
            </span>
          </div>
        </div>
      );
    }

    // 普通分类节点
    nodes.forEach(function(node) {
      var isActive = selectedCategory && selectedCategory.id === node.id;
      var hasChildren = node.children && node.children.length > 0;
      var isExpanded = expandedNodes.has(node.id);
      var isDragging = draggingNode && draggingNode.id === node.id;
      var isDropTarget = dropTarget === node.id;

      elements.push(
        <div key={node.id}>
          <div
            className={'tree-item importance-' + (node.importance || 'normal') + ' ' + (isActive ? 'active' : '') + (isDragging ? ' dragging' : '') + (isDropTarget ? ' drop-target' : '')}
            style={{ paddingLeft: (level * 20 + 8) + 'px' }}
            draggable={true}
            onClick={() => setSelectedCategory(node)}
            onDragStart={(e) => handleDragStart(e, node)}
            onDragOver={(e) => handleDragOver(e, node)}
            onDragLeave={handleDragLeave}
            onDrop={(e) => handleDrop(e, node)}
            onDragEnd={handleDragEnd}
          >
            <span 
              className="tree-toggle"
              onClick={(e) => {
                e.stopPropagation();
                if (hasChildren) toggleExpand(node.id);
              }}
              style={{ 
                visibility: hasChildren ? 'visible' : 'hidden',
                cursor: hasChildren ? 'pointer' : 'default'
              }}
            >
              {isExpanded ? '▾' : '▸'}
            </span>
            <span className="tree-node-content">
              <span className="tree-icon">
                {hasChildren ? (
                  isExpanded ? Icons.folderOpen : Icons.folder
                ) : Icons.file}
              </span>
              <span className="tree-label" title={node.name + ' (' + node.code + ')'}>{node.name}</span>
              <span className="tree-code" title={node.code}>({node.code})</span>
            </span>
          </div>
          {hasChildren && isExpanded && (
            <div className="tree-children">
              {renderTree(node.children, level + 1)}
            </div>
          )}
        </div>
      );
    });
    return elements;
  };

  const [sidebarWidth, setSidebarWidth] = React.useState(320);
  const [isDragging, setIsDragging] = React.useState(false);

  const handleMouseDown = function(e) {
    setIsDragging(true);
    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);
    document.body.classList.add('dragging-no-select');
  };

  const handleMouseMove = function(e) {
    if (!isDragging) return;
    const container = document.querySelector('.dict-layout');
    if (!container) return;
    const containerRect = container.getBoundingClientRect();
    const newWidth = e.clientX - containerRect.left;
    const clampedWidth = Math.max(200, Math.min(400, newWidth));
    setSidebarWidth(clampedWidth);
  };

  const handleMouseUp = function() {
    setIsDragging(false);
    document.removeEventListener('mousemove', handleMouseMove);
    document.removeEventListener('mouseup', handleMouseUp);
    document.body.classList.remove('dragging-no-select');
  };

  return (
    <div className="page-dict">
      <div className="dict-layout">
        <div 
          className={`dict-sidebar ${sidebarCollapsed ? 'collapsed' : ''}`}
          style={sidebarCollapsed ? {} : { width: `${sidebarWidth}px` }}
        >
          {sidebarCollapsed ? (
            <div className="sidebar-collapsed">
              <button
                className="sidebar-toggle collapsed"
                onClick={() => setSidebarCollapsed(false)}
                title="展开分类"
              >
                <span className="toggle-icon">📂</span>
              </button>
            </div>
          ) : (
            <>
              <div className="sidebar-header">
                <h3>字典分类</h3>
                <button
                  className="sidebar-toggle"
                  onClick={() => setSidebarCollapsed(true)}
                  title="收起分类"
                >
                  <span className="toggle-icon">📁</span>
                </button>
              </div>
              <div className="tree-container">
                {categories.length === 0 ? (
                  <div className="empty-state">暂无分类</div>
                ) : (
                  renderTree(categories)
                )}
              </div>
              <div 
                className={`dict-resizer ${isDragging ? 'dragging' : ''}`} 
                onMouseDown={handleMouseDown}
                title="拖拽调整大小"
              ></div>
            </>
          )}
        </div>
        <div className="dict-content">
          <div className="card-header dict-card-header">
            <div className="card-title-row">
              <h2>{selectedCategory ? selectedCategory.name : '请选择分类'}</h2>
              {selectedCategory && (
                <>
                  <span className="separator">|</span>
                  <span className="category-code">{selectedCategory.code}</span><span className="separator">|</span><span className="importance-badge" data-level={selectedCategory.importance || "normal"}>重要等级：{selectedCategory.importance === "system" ? "系统级" : selectedCategory.importance === "application" ? "应用级" : selectedCategory.importance === "business" ? "业务级" : selectedCategory.importance === "temp" ? "临时级" : "普通级"}<span className="importance-dot"></span></span>
                </>
              )}
            </div>
            <div className="card-header-actions">
              <p className="card-desc">{selectedCategory ? '请在下方管理该分类的字典项' : '请在左侧选择一个字典分类进行管理'}</p>
              <div className="card-actions">
                <button
                  className="btn btn-default btn-sm"
                  onClick={handleAddCategory}
                >+ 新增分类</button>
                {selectedCategory && (
                  <>
                    <button
                      className="btn btn-primary btn-sm"
                      onClick={handleAddItem}
                    >+ 新增字典项</button>
                    <button
                      className="btn btn-sm"
                      onClick={() => handleEditCategory(selectedCategory)}
                    >✏️ 编辑</button>
                    <button
                      className="btn btn-danger btn-sm"
                      onClick={() => handleDeleteCategory(selectedCategory)}
                    >🗑️ 删除</button>
                  </>
                )}
              </div>
            </div>
          </div>
          <div className="dict-content-inner">
            <div className="card-body">
              <div className="batch-table-wrapper">
                {!selectedCategory ? (
                  <div className="empty-state large">
                    <div className="empty-icon">🏠</div>
                    <h3>根目录</h3>
                    <p>点击上方"新增"按钮可以添加一级分类</p>
                  </div>
                ) : loading ? (
                  <div className="loading">加载中...</div>
                ) : (
                  <table className="batch-table">
                    <thead>
                      <tr>
                        <th>显示名称</th>
                        <th>编码</th>
                        <th>父级编码</th>
                        <th>引用分类</th>
                        <th>排序</th>
                        <th>状态</th>
                        <th>备注</th>
                        <th>操作</th>
                      </tr>
                    </thead>
                    <tbody>
                      {items.length === 0 ? (
                        <tr>
                          <td colSpan={8} className="empty-state">暂无字典项</td>
                        </tr>
                      ) : (
                        items.map(item => (
                          <tr key={item.id}>
                            <td>{item.label}</td>
                            <td><code>{item.value}</code></td>
                            <td>{item.parent_value || '—'}</td>
                            <td>{item.ref_category_code || '—'}</td>
                            <td>{item.sort}</td>
                            <td>
                              <span className={'badge ' + (item.status === 1 ? 'success' : 'danger')}>
                                {item.status === 1 ? '启用' : '禁用'}
                              </span>
                            </td>
                            <td>{item.remark || '—'}</td>
                            <td>
                              <button
                                className="btn btn-sm"
                                onClick={() => handleEditItem(item)}
                              >编辑</button>
                              <button
                                className="btn btn-danger btn-sm"
                                onClick={() => handleDeleteItem(item)}
                              >删除</button>
                            </td>
                          </tr>
                        ))
                      )}
                    </tbody>
                  </table>
                )}
              </div>
            </div>
          </div>
        </div>
      </div>
      {categoryModalVisible && editingCategory && (
        <div
          className="modal-overlay"
          onClick={() => setCategoryModalVisible(false)}
        >
          <div
            className="modal"
            onClick={e => e.stopPropagation()}
          >
            <div className="modal-header">
              <h3>{editingCategory.id ? '编辑分类' : '新增分类'}</h3>
              <button
                className="btn btn-icon"
                onClick={() => setCategoryModalVisible(false)}
              >✕</button>
            </div>
            <div className="modal-body">
              <div className="batch-form-section">
                <div className="batch-form-section-title">分类信息</div>
                <div className="form-group">
                  <label>父分类</label>
                  <input type="text" value={selectedCategory ? selectedCategory.name : '根目录'} disabled />
                </div>
                <div className="form-grid">
                  <div className="form-group">
                    <label>分类编码 *</label>
                    <input
                      type="text"
                      value={editingCategory.code}
                      onChange={e => setEditingCategory(Object.assign({}, editingCategory, { code: e.target.value }))}
                    />
                  </div>
                  <div className="form-group">
                    <label>分类名称 *</label>
                    <input
                      type="text"
                      value={editingCategory.name}
                      onChange={e => setEditingCategory(Object.assign({}, editingCategory, { name: e.target.value }))}
                    />
                  </div>
                </div>
                <div className="form-grid">
                  <div className="form-group">
                    <label>重要等级</label>
                    <select value={editingCategory.importance || "normal"} onChange={e => setEditingCategory(Object.assign({}, editingCategory, { importance: e.target.value }))}>
                      <option value="system">系统级</option>
                      <option value="application">应用级</option>
                      <option value="business">业务级</option>
                      <option value="normal">普通级</option>
                      <option value="temp">临时级</option>
                    </select>
                  </div>
                  <div className="form-group">
                    <label>排序</label>
                    <input
                      type="number"
                      value={editingCategory.sort}
                      onChange={e => setEditingCategory(Object.assign({}, editingCategory, { sort: parseInt(e.target.value) || 1 }))}
                    />
                  </div>
                </div>
                <div className="form-group">
                  <label>状态</label>
                  <select
                    value={editingCategory.status}
                    onChange={e => setEditingCategory(Object.assign({}, editingCategory, { status: parseInt(e.target.value) }))}
                  >
                    <option value={1}>启用</option>
                    <option value={0}>禁用</option>
                  </select>
                </div>
              </div>
              <div className="batch-form-section">
                <div className="batch-form-section-title">备注信息</div>
                <div className="form-group">
                  <label>备注</label>
                  <textarea
                    value={editingCategory.remark || ''}
                    onChange={e => setEditingCategory(Object.assign({}, editingCategory, { remark: e.target.value }))}
                  />
                </div>
              </div>
            </div>
            <div className="modal-footer">
              <button
                className="btn"
                onClick={() => setCategoryModalVisible(false)}
              >取消</button>
              <button
                className="btn btn-primary"
                onClick={handleSaveCategory}
              >保存</button>
            </div>
          </div>
        </div>
      )}
      {itemModalVisible && editingItem && (
        <div
          className="modal-overlay"
          onClick={() => setItemModalVisible(false)}
        >
          <div
            className="modal large"
            onClick={e => e.stopPropagation()}
          >
            <div className="modal-header">
              <h3>{editingItem.id ? '编辑字典项' : '新增字典项'}</h3>
              <button
                className="btn btn-icon"
                onClick={() => setItemModalVisible(false)}
              >✕</button>
            </div>
            <div className="modal-body">
              <div className="batch-form-section">
                <div className="batch-form-section-title">基本信息</div>
                <div className="form-grid">
                  <div className="form-group">
                    <label>显示名称 *</label>
                    <input
                      type="text"
                      value={editingItem.label}
                      onChange={e => setEditingItem(Object.assign({}, editingItem, { label: e.target.value }))}
                    />
                  </div>
                  <div className="form-group">
                    <label>编码 *</label>
                    <input
                      type="text"
                      value={editingItem.value}
                      onChange={e => setEditingItem(Object.assign({}, editingItem, { value: e.target.value }))}
                    />
                  </div>
                </div>
                <div className="form-grid">
                  <div className="form-group">
                    <label>父级编码</label>
                    <input
                      type="text"
                      value={editingItem.parent_value || ''}
                      onChange={e => setEditingItem(Object.assign({}, editingItem, { parent_value: e.target.value }))}
                    />
                  </div>
                  <div className="form-group">
                    <label>引用分类</label>
                    <input
                      type="text"
                      value={editingItem.ref_category_code || ''}
                      onChange={e => setEditingItem(Object.assign({}, editingItem, { ref_category_code: e.target.value }))}
                    />
                  </div>
                </div>
                <div className="form-grid">
                  <div className="form-group">
                    <label>排序</label>
                    <input
                      type="number"
                      value={editingItem.sort}
                      onChange={e => setEditingItem(Object.assign({}, editingItem, { sort: parseInt(e.target.value) || 1 }))}
                    />
                  </div>
                  <div className="form-group">
                    <label>状态</label>
                    <select
                      value={editingItem.status}
                      onChange={e => setEditingItem(Object.assign({}, editingItem, { status: parseInt(e.target.value) }))}
                    >
                      <option value={1}>启用</option>
                      <option value={0}>禁用</option>
                    </select>
                  </div>
                </div>
              </div>
              <div className="batch-form-section">
                <div className="batch-form-section-title">扩展信息</div>
                <div className="form-group">
                  <label>扩展字段 (JSON)</label>
                  <textarea
                    value={editingItem.extra ? JSON.stringify(editingItem.extra, null, 2) : ''}
                    onChange={e => setEditingItem(Object.assign({}, editingItem, { extra: e.target.value }))}
                  />
                </div>
                <div className="form-group">
                  <label>备注</label>
                  <textarea
                    value={editingItem.remark || ''}
                    onChange={e => setEditingItem(Object.assign({}, editingItem, { remark: e.target.value }))}
                  />
                </div>
              </div>
            </div>
            <div className="modal-footer">
              <button
                className="btn"
                onClick={() => setItemModalVisible(false)}
              >取消</button>
              <button
                className="btn btn-primary"
                onClick={handleSaveItem}
              >保存</button>
            </div>
          </div>
        </div>
      )}
      <ConfirmModal
        open={confirmModalVisible}
        onClose={setConfirmModalVisible}
        title={confirmConfig.title}
        message={confirmConfig.message}
        onConfirm={confirmConfig.onConfirm}
      />
    </div>
  );
}
