import { useState, useRef, useCallback } from 'react'
import { Upload, FileText, Zap, CheckCircle, AlertTriangle } from 'lucide-react'
import { api } from '../api'
import type { UploadResponse, BuildGraphResponse, AppSettings } from '../types'

interface Props {
  settings: AppSettings
  onDocumentReady: (id: string) => void
}

export function UploadPanel({ settings, onDocumentReady }: Props) {
  const [uploadResult, setUploadResult] = useState<UploadResponse | null>(null)
  const [buildResult, setBuildResult] = useState<BuildGraphResponse | null>(null)
  const [uploading, setUploading] = useState(false)
  const [building, setBuilding] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [dragging, setDragging] = useState(false)
  const inputRef = useRef<HTMLInputElement>(null)

  const handleFile = async (file: File) => {
    setError(null)
    setUploading(true)
    try {
      const res = await api.upload(file)
      setUploadResult(res)
      setBuildResult(null)
    } catch (e: any) {
      setError(String(e.message))
    } finally {
      setUploading(false)
    }
  }

  const handleSample = async () => {
    setError(null)
    setUploading(true)
    try {
      const res = await api.loadSample()
      setUploadResult(res)
      setBuildResult(null)
    } catch (e: any) {
      setError(String(e.message))
    } finally {
      setUploading(false)
    }
  }

  const handleBuild = async () => {
    if (!uploadResult) return
    setError(null)
    setBuilding(true)
    try {
      const res = await api.buildGraph(uploadResult.document_id, settings)
      setBuildResult(res)
      onDocumentReady(uploadResult.document_id)
    } catch (e: any) {
      setError(String(e.message))
    } finally {
      setBuilding(false)
    }
  }

  const onDragOver = useCallback((e: React.DragEvent) => {
    e.preventDefault()
    setDragging(true)
  }, [])

  const onDragLeave = useCallback((e: React.DragEvent) => {
    e.preventDefault()
    setDragging(false)
  }, [])

  const onDrop = useCallback((e: React.DragEvent) => {
    e.preventDefault()
    setDragging(false)
    const file = e.dataTransfer.files[0]
    if (file) handleFile(file)
  }, [])

  return (
    <div style={{ maxWidth: 640, display: 'flex', flexDirection: 'column', gap: 16 }}>
      <div
        className="card"
        onDragOver={onDragOver}
        onDragLeave={onDragLeave}
        onDrop={onDrop}
        style={{
          border: dragging ? '2px dashed var(--accent)' : undefined,
          transition: 'border 0.15s',
        }}
      >
        <div className="label">Document</div>
        <div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>
          <button className="btn-primary" onClick={() => inputRef.current?.click()} disabled={uploading}>
            <Upload size={14} style={{ display: 'inline', marginRight: 6 }} />
            Upload File
          </button>
          <button className="btn-secondary" onClick={handleSample} disabled={uploading}>
            <Zap size={14} style={{ display: 'inline', marginRight: 6 }} />
            Load Sample
          </button>
          <input
            ref={inputRef} type="file" accept=".txt,.md,.pdf"
            style={{ display: 'none' }}
            onChange={e => e.target.files?.[0] && handleFile(e.target.files[0])}
          />
        </div>
        <p style={{ fontSize: 12, color: dragging ? 'var(--accent)' : 'var(--muted)' }}>
          {dragging ? 'Drop to upload' : 'Accepts .txt, .md, .pdf — or drag & drop here'}
        </p>
        {uploading && <div style={{ marginTop: 12 }}><span className="spinner" /></div>}
      </div>

      {error && <div className="error-msg">{error}</div>}

      {uploadResult && (
        <div className="card">
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 12 }}>
            <FileText size={16} color="var(--accent2)" />
            <span style={{ fontWeight: 600 }}>{uploadResult.filename}</span>
            <span style={{ color: 'var(--muted)', fontSize: 12 }}>{uploadResult.char_count.toLocaleString()} chars</span>
          </div>
          <div style={{
            background: 'var(--bg3)', border: '1px solid var(--border)',
            borderRadius: 'var(--radius)', padding: 12,
            fontSize: 12, color: 'var(--muted)', fontFamily: 'monospace',
            whiteSpace: 'pre-wrap', maxHeight: 200, overflowY: 'auto',
            marginBottom: 12,
          }}>
            {uploadResult.text_preview}
          </div>
          <button className="btn-primary" onClick={handleBuild} disabled={building}>
            {building ? <><span className="spinner" style={{ width: 14, height: 14, marginRight: 6 }} />Building...</> : 'Build Causal Graph'}
          </button>
        </div>
      )}

      {buildResult && (
        <div className="card">
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 12 }}>
            <CheckCircle size={16} color="var(--success)" />
            <span style={{ fontWeight: 600, color: 'var(--success)' }}>Graph Built</span>
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 12, marginBottom: 12 }}>
            {[
              ['Chunks', buildResult.chunks],
              ['Triples', buildResult.triples],
              ['Nodes', buildResult.nodes],
              ['Edges', buildResult.edges],
              ['Cycles', buildResult.cycles.length],
            ].map(([k, v]) => (
              <div key={String(k)} style={{ textAlign: 'center', background: 'var(--bg3)', borderRadius: 'var(--radius)', padding: '8px 0' }}>
                <div style={{ fontSize: 20, fontWeight: 700, color: 'var(--accent2)' }}>{v}</div>
                <div style={{ fontSize: 11, color: 'var(--muted)' }}>{k}</div>
              </div>
            ))}
          </div>
          {buildResult.warnings.map((w, i) => (
            <div key={i} style={{ display: 'flex', alignItems: 'flex-start', gap: 6, fontSize: 12, color: 'var(--warning)', marginBottom: 4 }}>
              <AlertTriangle size={14} style={{ flexShrink: 0, marginTop: 1 }} />
              {w}
            </div>
          ))}
        </div>
      )}
    </div>
  )
}
