import { useState, useRef, useCallback } from 'react'

const MAX_FILE_SIZE_MB = 30
const MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024

function formatSize(bytes) {
  if (!Number.isFinite(bytes) || bytes <= 0) return '0 B'
  const units = ['B', 'KB', 'MB', 'GB']
  let value = bytes
  let idx = 0
  while (value >= 1024 && idx < units.length - 1) {
    value /= 1024
    idx += 1
  }
  return `${value.toFixed(value >= 10 || idx === 0 ? 0 : 1)} ${units[idx]}`
}

export default function UploadView({ onUpload, jobs, onOpenJob, onRetryJob }) {
  const [dragOver, setDragOver] = useState(false)
  const [isUploading, setIsUploading] = useState(false)
  const [validationErrors, setValidationErrors] = useState([])
  const [lastSelection, setLastSelection] = useState({ accepted: 0, rejected: 0 })
  const fileRef = useRef()
  const liveRegionRef = useRef()

  const announce = useCallback((message) => {
    if (!liveRegionRef.current) return
    liveRegionRef.current.textContent = ''
    window.requestAnimationFrame(() => {
      if (liveRegionRef.current) {
        liveRegionRef.current.textContent = message
      }
    })
  }, [])

  const handleFiles = useCallback(async (files) => {
    const accepted = []
    const rejected = []

    for (const file of Array.from(files || [])) {
      const validType = /\.(jpe?g|png|bmp|tiff?|pdf)$/i.test(file.name)
      if (!validType) {
        rejected.push(`${file.name}: unsupported file type`)
        continue
      }
      if (file.size > MAX_FILE_SIZE_BYTES) {
        rejected.push(`${file.name}: exceeds ${MAX_FILE_SIZE_MB} MB`)
        continue
      }
      accepted.push(file)
    }

    setValidationErrors(rejected)
    setLastSelection({ accepted: accepted.length, rejected: rejected.length })

    if (!accepted.length) {
      announce('No valid files selected.')
      return
    }

    setIsUploading(true)
    announce(`Uploading ${accepted.length} file${accepted.length > 1 ? 's' : ''}.`)
    try {
      await onUpload(accepted)
      announce(`${accepted.length} file${accepted.length > 1 ? 's' : ''} queued for processing.`)
    } finally {
      setIsUploading(false)
    }
  }, [onUpload])

  const onDrop = useCallback((e) => {
    e.preventDefault()
    setDragOver(false)
    void handleFiles(e.dataTransfer.files)
  }, [handleFiles])

  const doneJobs = jobs.filter(j => j.status === 'done')
  const activeJobs = jobs.filter(j => j.status !== 'done').slice(0, 8)

  return (
    <>
      <section className="upload-section">
        <span className="sr-only" ref={liveRegionRef} aria-live="polite" aria-atomic="true" />
        <div className="upload-hero">
          <h1>
            Extract Tables with <span className="gradient-text">AI Precision</span>
          </h1>
          <p>
            Upload document images or PDFs and let our 5-phase pipeline detect tables,
            recognize structure, perform OCR, and extract editable data — all in seconds.
          </p>
        </div>

        <div
          className={`upload-zone glass${dragOver ? ' drag-over' : ''}${isUploading ? ' is-uploading' : ''}`}
          role="button"
          tabIndex={0}
          aria-label="Upload documents"
          onDragOver={(e) => { e.preventDefault(); setDragOver(true) }}
          onDragLeave={() => setDragOver(false)}
          onDrop={onDrop}
          onClick={() => fileRef.current?.click()}
          onKeyDown={(e) => {
            if (e.key === 'Enter' || e.key === ' ') {
              e.preventDefault()
              fileRef.current?.click()
            }
          }}
        >
          <div className="upload-zone-icon">📄</div>
          <h3>{isUploading ? 'Uploading...' : 'Drop files here or click to browse'}</h3>
          <p>Supports JPG, PNG, BMP, TIFF, and PDF up to {MAX_FILE_SIZE_MB} MB each</p>
          <input
            ref={fileRef}
            type="file"
            accept=".jpg,.jpeg,.png,.bmp,.tiff,.tif,.pdf"
            multiple
            onChange={(e) => { void handleFiles(e.target.files) }}
          />
          <div className="upload-meta" aria-live="polite">
            <span>{lastSelection.accepted} accepted</span>
            <span>{lastSelection.rejected} rejected</span>
            <span>{jobs.filter((job) => job.status === 'processing' || job.status === 'queued').length} active</span>
          </div>
        </div>

        {validationErrors.length > 0 && (
          <div className="upload-errors" role="alert">
            {validationErrors.slice(0, 4).map((error) => (
              <div key={error} className="upload-error-item">{error}</div>
            ))}
          </div>
        )}

        <div className="pipeline-steps">
          {[
            ['1', 'Table Detection'],
            ['2', 'Structure Recognition'],
            ['3', 'Text Detection'],
            ['4', 'OCR Recognition'],
            ['5', 'Cell Assignment'],
          ].map(([n, label]) => (
            <div className="pipeline-step" key={n}>
              <span className="step-num">{n}</span>
              {label}
            </div>
          ))}
        </div>

        <section className="upload-guide glass" aria-label="User guide">
          <h3>User Guide</h3>
          <div className="upload-guide-grid">
            <div className="upload-guide-item">
              <strong>1. Upload files</strong>
              <p>Drag and drop or browse to select one or many images/PDFs.</p>
            </div>
            <div className="upload-guide-item">
              <strong>2. Wait for processing</strong>
              <p>Track queued and running jobs in the Upload Queue panel.</p>
            </div>
            <div className="upload-guide-item">
              <strong>3. Review results</strong>
              <p>Open any completed job to edit table structure and cell text.</p>
            </div>
            <div className="upload-guide-item">
              <strong>4. Export data</strong>
              <p>Export cleaned tables to CSV, Excel, or HTML from the studio.</p>
            </div>
          </div>
        </section>

        {!!activeJobs.length && (
          <div className="upload-queue glass">
            <div className="upload-queue-header">
              <h3>Upload Queue</h3>
              <span>{activeJobs.length} active</span>
            </div>
            <div className="upload-queue-list">
              {activeJobs.map((job) => (
                <div key={job.id} className="upload-queue-item">
                  <div>
                    <div className="upload-queue-name">{job.filename}</div>
                    <div className="upload-queue-meta">{job.status}</div>
                  </div>
                  <div className="upload-queue-actions">
                    {job.status === 'error' && (
                      <button type="button" className="btn btn-sm" onClick={() => onRetryJob?.(job)}>
                        Retry
                      </button>
                    )}
                    {job.status === 'processing' && <span className="badge">Running</span>}
                  </div>
                </div>
              ))}
            </div>
          </div>
        )}
      </section>

      {doneJobs.length > 0 && (
        <section className="jobs-section">
          <div className="jobs-header">
            <h2>Processed Files</h2>
            <span style={{ color: 'var(--text-muted)', fontSize: 14 }}>
              {doneJobs.length} file{doneJobs.length !== 1 ? 's' : ''}
            </span>
          </div>
          <div className="jobs-grid">
            {doneJobs.map(job => (
              <div key={job.id} className="job-card" onClick={() => onOpenJob(job)}>
                <img
                  className="job-card-thumb"
                  src={job.imageUrl}
                  alt={job.filename}
                  loading="lazy"
                />
                <div className="job-card-body">
                  <div>
                    <div className="job-card-name">{job.filename}</div>
                    <div className="job-card-meta">
                      {job.annotation?.tables?.length || 0} table(s) • {job.duration}s • {formatSize(job.size_bytes)}
                    </div>
                  </div>
                  <span className="badge badge-done">Done</span>
                </div>
              </div>
            ))}
          </div>
        </section>
      )}
    </>
  )
}
