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

const STATUS_POLL_MS = 1500   // poll /api/upload/status every 1.5s while running

export default function UploadModal({ open, onClose, onSuccess }) {
  const [phase, setPhase]       = useState('idle')   // idle | uploading | running | done | error
  const [message, setMessage]   = useState('')
  const [logs, setLogs]         = useState('')
  const [showLogs, setShowLogs] = useState(false)
  const [dragOver, setDragOver] = useState(false)
  const [filename, setFilename] = useState('')
  const fileRef  = useRef(null)
  const pollRef  = useRef(null)
  const logsRef  = useRef(null)

  // Auto-scroll logs
  useEffect(() => {
    if (logsRef.current) logsRef.current.scrollTop = logsRef.current.scrollHeight
  }, [logs])

  // Stop polling on unmount
  useEffect(() => () => clearInterval(pollRef.current), [])

  // Reset when modal opens
  useEffect(() => {
    if (open) {
      setPhase('idle'); setMessage(''); setLogs('')
      setShowLogs(false); setFilename(''); setDragOver(false)
      // Also reset server-side job state
      fetch('/api/upload/reset', { method: 'POST' }).catch(() => {})
    }
  }, [open])

  function startPolling() {
    clearInterval(pollRef.current)
    pollRef.current = setInterval(async () => {
      try {
        const [sRes, lRes] = await Promise.all([
          fetch('/api/upload/status'),
          fetch('/api/upload/logs'),
        ])
        const s = await sRes.json()
        const l = await lRes.json()
        setLogs(l.logs || '')
        setMessage(s.message || '')

        if (s.status === 'done') {
          clearInterval(pollRef.current)
          setPhase('done')
        } else if (s.status === 'error') {
          clearInterval(pollRef.current)
          setPhase('error')
          setShowLogs(true)
        }
      } catch {
        // network hiccup — keep polling
      }
    }, STATUS_POLL_MS)
  }

  async function handleFile(file) {
    if (!file) return
    if (!file.name.match(/\.(xlsx|xlsm|xls)$/i)) {
      setPhase('error')
      setMessage('Only .xlsx / .xlsm / .xls files are accepted.')
      return
    }
    setFilename(file.name)
    setPhase('uploading')
    setMessage('Uploading file…')

    const form = new FormData()
    form.append('file', file)

    try {
      const res = await fetch('/api/upload', { method: 'POST', body: form })
      const json = await res.json()
      if (!res.ok) {
        setPhase('error')
        setMessage(json.detail || 'Upload failed.')
        return
      }
      setPhase('running')
      setMessage('Pipeline started — processing data…')
      startPolling()
    } catch (err) {
      setPhase('error')
      setMessage('Cannot reach upload server. Is it running on port 8000?')
    }
  }

  const onDrop = useCallback(e => {
    e.preventDefault(); setDragOver(false)
    handleFile(e.dataTransfer.files[0])
  }, [])

  const onDragOver  = e => { e.preventDefault(); setDragOver(true) }
  const onDragLeave = () => setDragOver(false)

  function handleReload() {
    onClose()
    onSuccess(filename)   // pass filename back to caller
  }

  if (!open) return null

  const isRunning = phase === 'uploading' || phase === 'running'

  return (
    <div style={{
      position: 'fixed', inset: 0, zIndex: 1000,
      background: 'rgba(0,0,0,.45)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      padding: 20,
    }} onClick={e => { if (e.target === e.currentTarget && !isRunning) onClose() }}>

      <div style={{
        background: '#fff', borderRadius: 14, width: '100%', maxWidth: 540,
        boxShadow: '0 8px 40px rgba(0,0,0,.18)',
        display: 'flex', flexDirection: 'column', maxHeight: '90vh',
        overflow: 'hidden',
      }}>

        {/* Header */}
        <div style={{ padding: '18px 22px 14px', borderBottom: '1px solid var(--bd)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <div>
            <div style={{ fontWeight: 700, fontSize: 15, color: 'var(--gn)' }}>Upload New Data</div>
            <div style={{ fontSize: 10, color: 'var(--mt)', marginTop: 2 }}>Brand Onboarding Template (.xlsx)</div>
          </div>
          {!isRunning && (
            <button onClick={onClose} style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 18, color: 'var(--mt)', lineHeight: 1 }}>✕</button>
          )}
        </div>

        <div style={{ padding: '18px 22px', overflowY: 'auto', flex: 1 }}>

          {/* Drop zone — only shown when idle */}
          {phase === 'idle' && (
            <div
              onDrop={onDrop} onDragOver={onDragOver} onDragLeave={onDragLeave}
              onClick={() => fileRef.current?.click()}
              style={{
                border: `2px dashed ${dragOver ? 'var(--gn)' : 'var(--bd)'}`,
                borderRadius: 10,
                background: dragOver ? 'rgba(26,107,47,.04)' : 'var(--sf)',
                padding: '36px 20px',
                textAlign: 'center',
                cursor: 'pointer',
                transition: 'border-color .15s, background .15s',
              }}>
              <div style={{ fontSize: 32, marginBottom: 10 }}>📂</div>
              <div style={{ fontWeight: 600, fontSize: 13, color: 'var(--tx)' }}>
                Drag & drop your Excel file here
              </div>
              <div style={{ fontSize: 11, color: 'var(--mt)', marginTop: 4 }}>
                or click to browse — accepts .xlsx / .xlsm / .xls
              </div>
              <div style={{ marginTop: 14, fontSize: 10, color: 'var(--mt)', fontFamily: 'var(--mono)' }}>
                Required sheets: 1_Source_Data · 2_Brand_Config · 3_PPA_MT · 4_PPA_TT
              </div>
              <input ref={fileRef} type="file" accept=".xlsx,.xlsm,.xls"
                style={{ display: 'none' }}
                onChange={e => handleFile(e.target.files[0])} />
            </div>
          )}

          {/* Status area */}
          {phase !== 'idle' && (
            <div style={{ marginBottom: 16 }}>
              {/* File badge */}
              {filename && (
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 12,
                  background: 'var(--sf)', border: '1px solid var(--bd)', borderRadius: 8, padding: '8px 12px' }}>
                  <span style={{ fontSize: 18 }}>📄</span>
                  <span style={{ fontFamily: 'var(--mono)', fontSize: 11, color: 'var(--tx)', fontWeight: 600 }}>{filename}</span>
                </div>
              )}

              {/* Status pill */}
              <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 10 }}>
                {isRunning && <Spinner />}
                {phase === 'done'  && <span style={{ fontSize: 18 }}>✅</span>}
                {phase === 'error' && <span style={{ fontSize: 18 }}>❌</span>}
                <div>
                  <div style={{ fontSize: 12, fontWeight: 600, color: phase === 'error' ? 'var(--rd)' : phase === 'done' ? 'var(--gn)' : 'var(--tx)' }}>
                    {phase === 'uploading' && 'Uploading…'}
                    {phase === 'running'   && 'Pipeline running…'}
                    {phase === 'done'      && 'Complete!'}
                    {phase === 'error'     && 'Error'}
                  </div>
                  <div style={{ fontSize: 10, color: 'var(--mt)', marginTop: 1 }}>{message}</div>
                </div>
              </div>

              {/* Progress steps */}
              <Steps phase={phase} />
            </div>
          )}

          {/* Logs toggle */}
          {(phase === 'running' || phase === 'done' || phase === 'error') && (
            <div>
              <button onClick={() => setShowLogs(v => !v)} style={{
                background: 'none', border: '1px solid var(--bd)', borderRadius: 6,
                cursor: 'pointer', fontSize: 10, color: 'var(--mt)', padding: '4px 10px',
                fontFamily: 'var(--mono)', marginBottom: showLogs ? 8 : 0,
              }}>
                {showLogs ? '▲ Hide' : '▼ Show'} pipeline logs
              </button>
              {showLogs && (
                <pre ref={logsRef} style={{
                  background: '#1a1a1a', color: '#d4e6c3', borderRadius: 8,
                  padding: '12px 14px', fontSize: 9.5, fontFamily: 'var(--mono)',
                  maxHeight: 220, overflowY: 'auto', lineHeight: 1.5,
                  whiteSpace: 'pre-wrap', wordBreak: 'break-all',
                }}>
                  {logs || '(waiting for output…)'}
                </pre>
              )}
            </div>
          )}
        </div>

        {/* Footer buttons */}
        <div style={{ padding: '12px 22px', borderTop: '1px solid var(--bd)', display: 'flex', gap: 10, justifyContent: 'flex-end' }}>
          {phase === 'idle' && (
            <button onClick={onClose} style={btnStyle('secondary')}>Cancel</button>
          )}
          {phase === 'error' && (
            <>
              <button onClick={() => { setPhase('idle'); setMessage(''); setLogs('') }} style={btnStyle('secondary')}>Try Again</button>
              <button onClick={onClose} style={btnStyle('secondary')}>Close</button>
            </>
          )}
          {phase === 'done' && (
            <button onClick={handleReload} style={btnStyle('primary')}>
              Reload Dashboard
            </button>
          )}
        </div>
      </div>
    </div>
  )
}

function Steps({ phase }) {
  const steps = [
    { key: 'upload', label: 'File uploaded' },
    { key: 'pipeline', label: 'Pipeline running' },
    { key: 'copy', label: 'JSON files updated' },
  ]
  const activeIdx = phase === 'uploading' ? 0 : phase === 'running' ? 1 : phase === 'done' ? 3 : -1

  return (
    <div style={{ display: 'flex', gap: 0, marginBottom: 12 }}>
      {steps.map((s, i) => {
        const done   = phase === 'done' || (phase === 'running' && i === 0)
        const active = (phase === 'uploading' && i === 0) || (phase === 'running' && i === 1)
        const color  = done ? 'var(--gn)' : active ? 'var(--saf)' : 'var(--bd2)'
        return (
          <div key={s.key} style={{ display: 'flex', alignItems: 'center', gap: 0, flex: 1 }}>
            <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', minWidth: 0 }}>
              <div style={{ width: 20, height: 20, borderRadius: '50%', background: color, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 10, color: '#fff', fontWeight: 700, flexShrink: 0 }}>
                {done ? '✓' : i + 1}
              </div>
              <div style={{ fontSize: 9, color: done ? 'var(--gn)' : 'var(--mt)', marginTop: 3, textAlign: 'center', whiteSpace: 'nowrap' }}>{s.label}</div>
            </div>
            {i < steps.length - 1 && (
              <div style={{ flex: 1, height: 2, background: done ? 'var(--gn)' : 'var(--bd)', margin: '0 4px', marginBottom: 14 }} />
            )}
          </div>
        )
      })}
    </div>
  )
}

function Spinner() {
  return (
    <div style={{
      width: 18, height: 18, borderRadius: '50%', flexShrink: 0,
      border: '2.5px solid var(--bd)',
      borderTopColor: 'var(--gn)',
      animation: 'spin .7s linear infinite',
    }} />
  )
}

function btnStyle(variant) {
  const base = { border: 'none', borderRadius: 8, cursor: 'pointer', fontWeight: 600, fontSize: 12, padding: '8px 18px' }
  if (variant === 'primary') return { ...base, background: 'var(--gn)', color: '#fff' }
  return { ...base, background: 'var(--sf3)', color: 'var(--mt)', border: '1px solid var(--bd)' }
}
