import { useEffect, useRef, useState } from 'react'
import { deleteDocument, fetchDocuments } from '../api/api'
import { useToast } from './Toast'

function fileIcon(name) {
  const ext = name.split('.').pop()?.toLowerCase()
  const configs = {
    pdf:  { bg: 'bg-red-50',     text: 'text-red-500',     label: 'PDF' },
    docx: { bg: 'bg-blue-50',    text: 'text-blue-500',    label: 'DOC' },
    doc:  { bg: 'bg-blue-50',    text: 'text-blue-500',    label: 'DOC' },
    xlsx: { bg: 'bg-emerald-50', text: 'text-emerald-600', label: 'XLS' },
    xls:  { bg: 'bg-emerald-50', text: 'text-emerald-600', label: 'XLS' },
    png:  { bg: 'bg-purple-50',  text: 'text-purple-500',  label: 'IMG' },
    jpg:  { bg: 'bg-purple-50',  text: 'text-purple-500',  label: 'IMG' },
    jpeg: { bg: 'bg-purple-50',  text: 'text-purple-500',  label: 'IMG' },
  }
  return configs[ext] ?? { bg: 'bg-stone-100', text: 'text-stone-500', label: 'DOC' }
}

function formatBytes(bytes) {
  if (!bytes) return ''
  if (bytes < 1024) return `${bytes} B`
  if (bytes < 1048576) return `${(bytes / 1024).toFixed(0)} KB`
  return `${(bytes / 1048576).toFixed(1)} MB`
}

export default function DocumentList({ refreshSignal, onDocumentSelect }) {
  const toast = useToast()
  const [docs, setDocs] = useState([])
  const [loading, setLoading] = useState(false)
  const [fetchError, setFetchError] = useState(false)
  const [deletingDoc, setDeletingDoc] = useState(null)
  const [confirmDelete, setConfirmDelete] = useState(null)
  // Track the confirm-timeout per document so switching docs doesn't clear the wrong timer
  const confirmTimerRef = useRef(null)

  const load = async () => {
    setLoading(true)
    setFetchError(false)
    try { setDocs(await fetchDocuments()) }
    catch {
      setFetchError(true)
      toast.error('Failed to load documents.')
    }
    finally { setLoading(false) }
  }

  // eslint-disable-next-line react-hooks/exhaustive-deps
  useEffect(() => { load() }, [refreshSignal])

  const handleDelete = async (name) => {
    if (confirmDelete !== name) {
      // Cancel any pending confirmation timer before starting a new one
      if (confirmTimerRef.current) clearTimeout(confirmTimerRef.current)
      setConfirmDelete(name)
      confirmTimerRef.current = setTimeout(() => {
        setConfirmDelete(null)
        confirmTimerRef.current = null
      }, 3000)
      return
    }
    if (confirmTimerRef.current) { clearTimeout(confirmTimerRef.current); confirmTimerRef.current = null }
    setConfirmDelete(null); setDeletingDoc(name)
    try { await deleteDocument(name); toast.success(`"${name}" deleted.`); await load() }
    catch { toast.error('Failed to delete document.') }
    finally { setDeletingDoc(null) }
  }

  if (loading && !docs.length) {
    return (
      <div className="space-y-2">
        {[1, 2, 3].map(i => (
          <div key={i} className="h-12 rounded-xl bg-stone-100 animate-pulse" />
        ))}
      </div>
    )
  }

  if (fetchError) {
    return (
      <div className="flex flex-col items-center gap-2 py-6 text-center">
        <div className="w-10 h-10 rounded-xl bg-red-50 flex items-center justify-center">
          <ErrorIcon />
        </div>
        <p className="text-red-500 text-sm font-medium">Failed to load documents</p>
        <button onClick={load}
          className="text-xs text-brand hover:underline font-medium transition-colors">
          Try again
        </button>
      </div>
    )
  }

  if (!docs.length) {
    return (
      <div className="flex flex-col items-center gap-2 py-6 text-center">
        <div className="w-10 h-10 rounded-xl bg-stone-100 flex items-center justify-center">
          <EmptyIcon />
        </div>
        <p className="text-stone-500 text-sm font-medium">No documents yet</p>
        <p className="text-stone-400 text-xs">Upload a document to get started</p>
      </div>
    )
  }

  return (
    <ul className="space-y-1">
      {docs.map(doc => {
        const icon = fileIcon(doc.name)
        const isDeleting = deletingDoc === doc.name
        const isConfirm = confirmDelete === doc.name

        return (
          <li key={doc.name}
            className={`group flex items-center gap-2.5 rounded-xl px-3 py-2.5
              transition-all duration-150 cursor-pointer
              ${isDeleting ? 'opacity-40' : 'hover:bg-brand/[0.05] hover:border-brand/15'}
              border border-transparent`}
            onClick={() => onDocumentSelect?.(doc.name)}>

            <div className={`w-8 h-8 rounded-lg ${icon.bg} flex items-center
              justify-center shrink-0 border border-black/5`}>
              <span className={`text-[9px] font-bold ${icon.text}`}>{icon.label}</span>
            </div>

            <div className="flex-1 min-w-0">
              <p className="text-sm text-stone-700 truncate leading-tight font-medium"
                title={doc.name}>{doc.name}</p>
              <p className="text-[10px] text-stone-400 leading-tight mt-0.5">
                {[doc.chunks ? `${doc.chunks} chunks` : null, doc.size ? formatBytes(doc.size) : null]
                  .filter(Boolean).join(' · ')}
              </p>
            </div>

            <button onClick={e => { e.stopPropagation(); handleDelete(doc.name) }}
              disabled={isDeleting}
              className={`shrink-0 w-7 h-7 rounded-lg flex items-center justify-center
                transition-all duration-150
                opacity-100 lg:opacity-0 lg:group-hover:opacity-100
                ${isConfirm
                  ? 'bg-red-50 text-red-500 border border-red-200 lg:opacity-100'
                  : 'hover:bg-red-50 text-stone-400 hover:text-red-500 border border-transparent hover:border-red-200'}`}
              title={isConfirm ? 'Click again to confirm delete' : 'Delete document'}>
              {isConfirm ? <ConfirmIcon /> : <TrashIcon />}
            </button>
          </li>
        )
      })}
    </ul>
  )
}

const EmptyIcon = () => (
  <svg className="w-5 h-5 text-stone-400" fill="none" stroke="currentColor" strokeWidth={1.5} viewBox="0 0 24 24">
    <path strokeLinecap="round" strokeLinejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m2.25 0H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z"/>
  </svg>
)
const ErrorIcon = () => (
  <svg className="w-5 h-5 text-red-400" fill="none" stroke="currentColor" strokeWidth={1.5} viewBox="0 0 24 24">
    <path strokeLinecap="round" strokeLinejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"/>
  </svg>
)
const TrashIcon = () => (
  <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" strokeWidth={2} viewBox="0 0 24 24">
    <path strokeLinecap="round" strokeLinejoin="round" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0"/>
  </svg>
)
const ConfirmIcon = () => (
  <svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" strokeWidth={2.5} viewBox="0 0 24 24">
    <path strokeLinecap="round" strokeLinejoin="round" d="M4.5 12.75l6 6 9-13.5"/>
  </svg>
)
