import { useCallback, useState } from 'react'
import { useDropzone } from 'react-dropzone'
import { extractDocument } from '../lib/extractor'
import { chunkPages } from '../lib/chunker'
import { uploadChunks } from '../api/api'
import { useToast } from './Toast'

const ACCEPTED = {
  'application/pdf': ['.pdf'],
  'application/vnd.openxmlformats-officedocument.wordprocessingml.document': ['.docx'],
  'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': ['.xlsx'],
  'application/vnd.ms-excel': ['.xls'],
  'image/png': ['.png'],
  'image/jpeg': ['.jpg', '.jpeg'],
}

const STAGES = [
  'Extracting text in browser…',
  'Chunking document…',
  'Embedding & indexing…',
  'Done!',
]

export default function FileUpload({ onUploaded }) {
  const toast = useToast()
  const [uploading, setUploading] = useState(false)
  const [stage, setStage] = useState('')
  const [stageIndex, setStageIndex] = useState(0)
  const [fileName, setFileName] = useState('')
  const [uploadError, setUploadError] = useState('')

  const onDrop = useCallback(async (accepted, rejected) => {
    if (rejected.length) { toast.error('Unsupported file type. Use PDF, DOCX, XLSX, PNG or JPG.'); return }
    if (!accepted.length) return

    const file = accepted[0]
    setUploading(true); setUploadError(''); setFileName(file.name); setStageIndex(0); setStage(STAGES[0])

    try {
      const pages = await extractDocument(file)
      if (!pages.length) { toast.error('No text could be extracted.'); return }

      setStageIndex(1); setStage(STAGES[1])
      const chunks = chunkPages(pages)

      setStageIndex(2); setStage(STAGES[2])
      const result = await uploadChunks(file.name, chunks)

      setStageIndex(3); setStage(STAGES[3])
      toast.success(`"${result.documentName}" ready — ${result.chunksCreated} chunks embedded`)
      onUploaded?.()
    } catch (err) {
      const msg = err.response?.data?.error ?? err.message ?? 'Upload failed.'
      setUploadError(msg)
      toast.error(msg)
    } finally {
      setUploading(false); setStage(''); setFileName(''); setStageIndex(0)
    }
  }, [onUploaded, toast])

  const { getRootProps, getInputProps, isDragActive } = useDropzone({
    onDrop, accept: ACCEPTED, multiple: false, disabled: uploading,
  })

  const progress = uploading ? Math.round((stageIndex / (STAGES.length - 1)) * 100) : 0

  return (
    <div className="space-y-3">
      <div {...getRootProps()}
        className={`relative border-2 border-dashed rounded-2xl p-4 text-center
          cursor-pointer transition-all duration-200 overflow-hidden group
          ${isDragActive
            ? 'border-brand bg-brand/[0.06] scale-[1.01]'
            : 'border-stone-300 hover:border-brand/60 hover:bg-brand/[0.03] bg-cream-100/50'}
          ${uploading ? 'opacity-60 pointer-events-none' : ''}`}>
        <input {...getInputProps()} />

        {isDragActive && (
          <div className="absolute inset-0 bg-gradient-to-br from-brand/5 to-brand/10 animate-pulse"/>
        )}

        <div className="relative flex flex-col items-center gap-2">
          <div className={`w-10 h-10 rounded-xl flex items-center justify-center
            transition-colors duration-200
            ${isDragActive ? 'bg-brand/20' : 'bg-stone-100 group-hover:bg-brand/10'}`}>
            <UploadIcon active={isDragActive} />
          </div>

          {isDragActive ? (
            <p className="text-brand font-semibold text-sm">Drop to upload</p>
          ) : (
            <>
              <div>
                <p className="text-stone-700 font-medium text-sm">Drag & drop a document</p>
                <p className="text-stone-400 text-xs mt-0.5">or click to browse</p>
              </div>
              <div className="flex flex-wrap justify-center gap-1">
                {['PDF', 'DOCX', 'XLSX', 'PNG', 'JPG'].map(f => (
                  <span key={f} className="text-[9px] font-bold px-2 py-0.5 rounded-full
                    bg-white border border-stone-200 text-stone-500">
                    {f}
                  </span>
                ))}
              </div>
              <p className="text-[10px] text-emerald-600 flex items-center gap-1 font-medium">
                <LockIcon /> Original file stays on your device — only text is sent
              </p>
            </>
          )}
        </div>
      </div>

      {uploadError && !uploading && (
        <div className="flex items-start gap-2 rounded-xl border border-red-200 bg-red-50 p-3">
          <svg className="w-4 h-4 text-red-500 shrink-0 mt-0.5" fill="none" stroke="currentColor" strokeWidth={2} 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>
          <div className="flex-1 min-w-0">
            <p className="text-xs font-semibold text-red-700">Upload failed</p>
            <p className="text-[11px] text-red-500 mt-0.5 break-words">{uploadError}</p>
          </div>
          <button onClick={() => setUploadError('')}
            className="text-red-400 hover:text-red-600 transition-colors shrink-0">
            <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="M6 18L18 6M6 6l12 12"/>
            </svg>
          </button>
        </div>
      )}

      {uploading && (
        <div className="space-y-2 bg-white rounded-xl border border-stone-200 p-3">
          <div className="flex justify-between text-xs">
            <span className="text-stone-600 font-medium">{stage}</span>
            <span className="text-brand font-bold">{progress}%</span>
          </div>
          <div className="h-1.5 bg-stone-100 rounded-full overflow-hidden">
            <div className="h-full bg-brand rounded-full transition-all duration-500 shadow-brand-sm"
              style={{ width: `${Math.max(progress, 5)}%` }} />
          </div>
          {fileName && (
            <p className="text-[10px] text-stone-400 truncate">{fileName}</p>
          )}
        </div>
      )}
    </div>
  )
}

const UploadIcon = ({ active }) => (
  <svg className={`w-5 h-5 transition-colors ${active ? 'text-brand' : 'text-stone-400'}`}
    fill="none" stroke="currentColor" strokeWidth={1.8} viewBox="0 0 24 24">
    <path strokeLinecap="round" strokeLinejoin="round"
      d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5"/>
  </svg>
)

const LockIcon = () => (
  <svg className="w-3 h-3" fill="none" stroke="currentColor" strokeWidth={2} viewBox="0 0 24 24">
    <path strokeLinecap="round" strokeLinejoin="round"
      d="M16.5 10.5V6.75a4.5 4.5 0 10-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H6.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z"/>
  </svg>
)
