import { useEffect, useMemo, useRef, useState } from 'react'
import CategoryTree from '../components/CategoryTree.jsx'
import { useCategories } from '../contexts/CategoryContext.jsx'
import { useFiles } from '../contexts/FilesContext.jsx'
import { getNodePath } from '../components/NodePickerModal.jsx'

const EXT_COLOR = {
  pdf: 'bg-rose-50 text-rose-700',
  docx: 'bg-blue-50 text-blue-700',
  xlsx: 'bg-emerald-50 text-emerald-700',
  pptx: 'bg-orange-50 text-orange-700',
  md: 'bg-gray-100 text-gray-700',
  png: 'bg-purple-50 text-purple-700',
  jpg: 'bg-purple-50 text-purple-700',
  txt: 'bg-gray-100 text-gray-700'
}

function formatSize(bytes) {
  if (!bytes) return '-'
  if (bytes < 1024) return `${bytes} B`
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
  return `${(bytes / 1024 / 1024).toFixed(2)} MB`
}

function formatTime(iso) {
  if (!iso) return '-'
  const d = new Date(iso)
  const yyyy = d.getFullYear()
  const mm = String(d.getMonth() + 1).padStart(2, '0')
  const dd = String(d.getDate()).padStart(2, '0')
  const hh = String(d.getHours()).padStart(2, '0')
  const mi = String(d.getMinutes()).padStart(2, '0')
  return `${yyyy}-${mm}-${dd} ${hh}:${mi}`
}

function UploadModal({ open, defaultCategoryId, onClose, onSubmit }) {
  const [name, setName] = useState('')
  const [summary, setSummary] = useState('')
  if (!open) return null
  const reset = () => { setName(''); setSummary('') }
  const submit = () => {
    if (!name.trim()) return
    onSubmit({ name: name.trim(), summary: summary.trim(), category_id: defaultCategoryId })
    reset()
  }
  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/30" onClick={onClose}>
      <div className="bg-white rounded-xl shadow-xl w-[440px]" onClick={e => e.stopPropagation()}>
        <div className="px-5 py-4 border-b border-gray-100 flex items-center justify-between">
          <div className="text-[15px] font-semibold text-gray-900">上传流程文件</div>
          <button onClick={onClose} className="text-gray-400 hover:text-gray-600 text-[18px] leading-none">×</button>
        </div>
        <div className="px-5 py-4 space-y-3">
          <div>
            <label className="block text-[12px] text-gray-600 mb-1">文件名（含后缀）</label>
            <input
              value={name}
              onChange={e => setName(e.target.value)}
              placeholder="例如：方案-V1.docx"
              className="w-full px-3 py-2 text-[13px] border border-gray-200 rounded-md focus:outline-none focus:border-brand-400"
            />
          </div>
          <div>
            <label className="block text-[12px] text-gray-600 mb-1">简要描述</label>
            <textarea
              value={summary}
              onChange={e => setSummary(e.target.value)}
              rows={3}
              placeholder="一句话说明文件用途，便于 Skill 调用时识别"
              className="w-full px-3 py-2 text-[13px] border border-gray-200 rounded-md focus:outline-none focus:border-brand-400"
            />
          </div>
          <div className="text-[12px] text-gray-400">将挂载在当前选中的流程节点上。</div>
        </div>
        <div className="px-5 py-3 border-t border-gray-100 flex items-center justify-end gap-2">
          <button onClick={onClose} className="px-3 py-1.5 text-[13px] rounded-md text-gray-600 border border-gray-200 hover:bg-gray-50">取消</button>
          <button onClick={submit} className="px-3.5 py-1.5 text-[13px] rounded-md text-white bg-brand-600 hover:bg-brand-700">确认上传</button>
        </div>
      </div>
    </div>
  )
}

export default function ProcessFiles() {
  const { flat } = useCategories()
  const { files, getFilesUnder, addFile, deleteFile, updateFile } = useFiles()

  const [selectedId, setSelectedId] = useState(null)
  const [keyword, setKeyword] = useState('')
  const [uploadOpen, setUploadOpen] = useState(false)
  const [editingId, setEditingId] = useState(null)
  const [editingSummary, setEditingSummary] = useState('')
  const listScrollRef = useRef(null)

  // 切换节点后滚动到顶部，避免上个节点的滚动位置让人以为加载失败
  useEffect(() => {
    if (listScrollRef.current) {
      listScrollRef.current.scrollTop = 0
    }
  }, [selectedId])

  // 当前节点（含子孙）下的文件
  const filesInScope = useMemo(() => {
    if (selectedId == null) return files
    return getFilesUnder(selectedId, flat)
  }, [files, selectedId, getFilesUnder, flat])

  const filtered = useMemo(() => {
    const k = keyword.trim().toLowerCase()
    if (!k) return filesInScope
    return filesInScope.filter(f =>
      f.name.toLowerCase().includes(k) ||
      (f.summary || '').toLowerCase().includes(k)
    )
  }, [filesInScope, keyword])

  const selectedNodePath = selectedId != null ? getNodePath(selectedId, flat) : '全部节点'

  const handleUpload = (payload) => {
    if (selectedId == null) {
      window.alert('请先在左侧选择一个流程节点')
      return
    }
    addFile({ ...payload, uploader: '詹老师' })
    setUploadOpen(false)
  }

  const handleDelete = (file) => {
    if (window.confirm(`确认删除文件「${file.name}」？`)) deleteFile(file.id)
  }

  const startEditSummary = (file) => {
    setEditingId(file.id)
    setEditingSummary(file.summary || '')
  }
  const commitEditSummary = (id) => {
    updateFile(id, { summary: editingSummary.trim() })
    setEditingId(null)
  }

  return (
    <div className="flex flex-1 overflow-hidden">
      <CategoryTree selectedId={selectedId} onSelect={n => setSelectedId(n ? n.id : null)} />

      <div ref={listScrollRef} className="flex-1 overflow-auto">
        <div className="p-6">
          {/* 顶部工具栏 */}
          <div className="flex items-start justify-between gap-4 mb-4">
            <div className="min-w-0">
              <div className="text-[12px] text-gray-400">流程文件库</div>
              <h1 className="text-[18px] font-semibold text-gray-900 mt-0.5 truncate">{selectedNodePath}</h1>
              <div className="text-[12px] text-gray-500 mt-1">
                {selectedId == null
                  ? `共 ${files.length} 个文件，挂载在流程架构的各节点上。选中节点可只看该节点（含子孙）的文件。`
                  : `该节点（含子孙）共 ${filesInScope.length} 个文件。这些文件可作为该节点关联的 Skill 上下文。`}
              </div>
            </div>
            <button
              onClick={() => setUploadOpen(true)}
              disabled={selectedId == null}
              className="flex-shrink-0 px-3.5 py-2 text-[13px] rounded-md text-white bg-brand-600 hover:bg-brand-700 disabled:bg-gray-300 disabled:cursor-not-allowed"
              title={selectedId == null ? '请先在左侧选中一个节点再上传' : '上传文件到当前节点'}
            >＋ 上传文件</button>
          </div>

          {/* 搜索 */}
          <div className="mb-4">
            <input
              value={keyword}
              onChange={e => setKeyword(e.target.value)}
              placeholder="搜索文件名或描述..."
              className="w-full max-w-md px-3 py-2 text-[13px] border border-gray-200 rounded-md focus:outline-none focus:border-brand-400"
            />
          </div>

          {/* 文件列表 */}
          {filtered.length === 0 ? (
            <div className="bg-white border border-gray-200 rounded-xl p-12 text-center text-gray-400 text-[13px]">
              {keyword ? '没有匹配的文件' : (selectedId == null ? '暂无文件' : '该节点下还没有文件，点击右上角"上传文件"添加')}
            </div>
          ) : (
            <div className="bg-white border border-gray-200 rounded-xl overflow-hidden">
              <table className="w-full text-[13px]">
                <thead className="bg-gray-50 text-gray-500 text-[12px]">
                  <tr>
                    <th className="text-left font-medium px-4 py-2.5">文件</th>
                    <th className="text-left font-medium px-4 py-2.5 w-[34%]">描述</th>
                    <th className="text-left font-medium px-4 py-2.5 w-[20%]">挂载节点</th>
                    <th className="text-left font-medium px-4 py-2.5 w-[110px]">大小</th>
                    <th className="text-left font-medium px-4 py-2.5 w-[160px]">更新时间</th>
                    <th className="text-right font-medium px-4 py-2.5 w-[100px]">操作</th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-gray-100">
                  {filtered.map(f => (
                    <tr key={f.id} className="hover:bg-gray-50/70">
                      <td className="px-4 py-3">
                        <div className="flex items-center gap-2">
                          <span className={`text-[10px] uppercase px-1.5 py-0.5 rounded ${EXT_COLOR[f.ext] || 'bg-gray-100 text-gray-700'}`}>{f.ext}</span>
                          <span className="text-gray-800 truncate max-w-[280px]" title={f.name}>{f.name}</span>
                        </div>
                      </td>
                      <td className="px-4 py-3 text-gray-600">
                        {editingId === f.id ? (
                          <div className="flex items-center gap-1">
                            <input
                              autoFocus
                              value={editingSummary}
                              onChange={e => setEditingSummary(e.target.value)}
                              onKeyDown={e => {
                                if (e.key === 'Enter') commitEditSummary(f.id)
                                else if (e.key === 'Escape') setEditingId(null)
                              }}
                              className="flex-1 min-w-0 px-1.5 py-0.5 text-[12px] border border-brand-300 rounded outline-none focus:border-brand-500"
                            />
                            <button onClick={() => commitEditSummary(f.id)} className="text-brand-600 text-[11px] px-1">✓</button>
                            <button onClick={() => setEditingId(null)} className="text-gray-400 text-[11px] px-1">✕</button>
                          </div>
                        ) : (
                          <span
                            className="cursor-text hover:text-gray-900"
                            onClick={() => startEditSummary(f)}
                            title="点击编辑描述"
                          >{f.summary || <span className="text-gray-300">点击添加描述</span>}</span>
                        )}
                      </td>
                      <td className="px-4 py-3 text-gray-500 text-[12px]" title={getNodePath(f.category_id, flat)}>
                        <span className="truncate inline-block max-w-[200px] align-middle">{getNodePath(f.category_id, flat)}</span>
                      </td>
                      <td className="px-4 py-3 text-gray-500">{formatSize(f.size)}</td>
                      <td className="px-4 py-3 text-gray-500">{formatTime(f.updated_at)}</td>
                      <td className="px-4 py-3 text-right">
                        <button
                          onClick={() => handleDelete(f)}
                          className="text-gray-400 hover:text-rose-500 text-[12px] px-1.5"
                          title="删除"
                        >删除</button>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </div>
      </div>

      <UploadModal
        open={uploadOpen}
        defaultCategoryId={selectedId}
        onClose={() => setUploadOpen(false)}
        onSubmit={handleUpload}
      />
    </div>
  )
}
