'use client'

import { useCallback, useEffect, useRef, useState } from 'react'
import { Download, FileText, GripVertical, Loader2, Pencil, Plus, Trash2, Upload, User, X } from 'lucide-react'
import './ApplicantsView.css'

interface Applicant {
  id: string
  name: string
  email: string
  phone: string
  cvName: string
  hasCv: boolean
  cvSize: number
  updatedAt: string
}

const formatSize = (bytes: number) => {
  if (bytes < 1024) return `${bytes} B`
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`
}

const formatDate = (value?: string) =>
  value ? new Date(value).toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric' }) : '—'

export function ApplicantsView() {
  const [applicants, setApplicants] = useState<Applicant[]>([])
  const [loading, setLoading] = useState(true)
  const [adding, setAdding] = useState(false)
  const [editing, setEditing] = useState<Applicant | null>(null)
  const [error, setError] = useState('')

  const [form, setForm] = useState({ name: '', email: '', phone: '' })
  const [file, setFile] = useState<File | null>(null)
  const [uploading, setUploading] = useState(false)
  const [formError, setFormError] = useState('')
  const [dragging, setDragging] = useState(false)
  const [draggingCvId, setDraggingCvId] = useState<string | null>(null)
  const fileInputRef = useRef<HTMLInputElement>(null)

  const load = useCallback(async () => {
    setLoading(true)
    setError('')
    try {
      const res = await fetch('/api/applicants')
      if (!res.ok) throw new Error('Failed to load applicants')
      const data = await res.json()
      setApplicants(data.applicants || [])
    } catch (err: any) {
      setError(err.message || 'Failed to load applicants')
    } finally {
      setLoading(false)
    }
  }, [])

  useEffect(() => {
    load()
  }, [load])

  const submit = async () => {
    if (!form.name.trim() || !form.email.trim()) {
      setFormError('Name and email are required.')
      return
    }
    setUploading(true)
    setFormError('')
    try {
      const body = new FormData()
      body.set('name', form.name)
      body.set('email', form.email)
      body.set('phone', form.phone)
      if (file) body.set('cv', file)

      const url = editing ? `/api/applicants/${editing.id}` : '/api/applicants'
      const res = await fetch(url, { method: editing ? 'PATCH' : 'POST', body })
      if (!res.ok) {
        const d = await res.json().catch(() => ({}))
        throw new Error(d.error || 'Failed to save applicant')
      }
      setForm({ name: '', email: '', phone: '' })
      setFile(null)
      setAdding(false)
      setEditing(null)
      await load()
    } catch (err: any) {
      setFormError(err.message || 'Failed to save applicant')
    } finally {
      setUploading(false)
    }
  }

  const openNew = () => {
    setAdding((v) => !v)
    setEditing(null)
    setForm({ name: '', email: '', phone: '' })
    setFile(null)
    setFormError('')
  }

  const openEdit = (a: Applicant) => {
    setEditing(a)
    setAdding(true)
    setForm({ name: a.name, email: a.email, phone: a.phone })
    setFile(null)
    setFormError('')
  }

  const handleDragOver = (e: React.DragEvent) => {
    e.preventDefault()
    setDragging(true)
  }

  const handleDragLeave = (e: React.DragEvent) => {
    e.preventDefault()
    setDragging(false)
  }

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault()
    setDragging(false)
    const droppedFile = e.dataTransfer.files[0]
    if (droppedFile && isCVFile(droppedFile)) {
      setFile(droppedFile)
    }
  }

  const isCVFile = (file: File) => {
    const allowedTypes = ['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document']
    return allowedTypes.includes(file.type) || file.name.match(/\.(pdf|doc|docx)$/i)
  }

  const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
    const selectedFile = e.target.files?.[0]
    if (selectedFile) {
      setFile(selectedFile)
    }
  }

  const handleCvDragStart = async (e: React.DragEvent, applicant: Applicant) => {
    if (!applicant.hasCv) return
    setDraggingCvId(applicant.id)

    const fileName = applicant.cvName || 'cv.pdf'
    const downloadUrl = `/api/applicants/${applicant.id}/cv`

    e.dataTransfer.effectAllowed = 'copy'
    e.dataTransfer.setData('text/plain', downloadUrl)
    e.dataTransfer.setData('text/uri-list', downloadUrl)

    try {
      const res = await fetch(downloadUrl)
      if (res.ok) {
        const blob = await res.blob()
        const file = new File([blob], fileName, { type: blob.type || 'application/pdf' })
        e.dataTransfer.items.add(file)
      }
    } catch {
      // text/plain fallback already set
    }
  }

  const handleCvDragEnd = () => {
    setDraggingCvId(null)
  }

  const remove = async (id: string) => {
    if (!confirm('Delete this applicant and their CV?')) return
    try {
      await fetch(`/api/applicants/${id}`, { method: 'DELETE' })
      await load()
    } catch {
      // ignore
    }
  }

  return (
    <section className="panel applicants-panel">
      <div className="panel-heading">
        <div>
          <h2>Applicants</h2>
          <p>Upload and store CVs for your candidates. Download anytime when applying.</p>
        </div>
        <button className="outline-button" onClick={openNew}>
          {adding ? <X size={14} /> : <Plus size={14} />} {adding ? 'Cancel' : 'Add applicant'}
        </button>
      </div>

      {adding && (
        <div className="upload-card">
          <div className="form-grid">            <div className="field">
              <label>Full name</label>
              <input
                value={form.name}
                onChange={(e) => setForm({ ...form, name: e.target.value })}
                placeholder="Applicant name"
              />
            </div>
            <div className="field">
              <label>Email</label>
              <input
                type="email"
                value={form.email}
                onChange={(e) => setForm({ ...form, email: e.target.value })}
                placeholder="name@example.com"
              />
            </div>
            <div className="field">
              <label>Phone</label>
              <input
                value={form.phone}
                onChange={(e) => setForm({ ...form, phone: e.target.value })}
                placeholder="+44 ..."
              />
            </div>
            <div className="field full">
              <label>CV file</label>
              <div
                className={`drop-zone ${dragging ? 'dragging' : ''} ${file ? 'has-file' : ''}`}
                onDragOver={handleDragOver}
                onDragLeave={handleDragLeave}
                onDrop={handleDrop}
                onClick={() => fileInputRef.current?.click()}
              >
                <input
                  ref={fileInputRef}
                  type="file"
                  accept=".pdf,.doc,.docx"
                  onChange={handleFileSelect}
                  className="file-input-hidden"
                />
                {file ? (
                  <div className="drop-zone-content">
                    <FileText size={24} className="drop-zone-icon" />
                    <div className="drop-zone-text">
                      <span className="file-name">{file.name}</span>
                      <span className="file-size">{formatSize(file.size)}</span>
                    </div>
                    <button
                      type="button"
                      className="remove-file"
                      onClick={(e) => {
                        e.stopPropagation()
                        setFile(null)
                      }}
                    >
                      <X size={16} />
                    </button>
                  </div>
                ) : (
                  <div className="drop-zone-content">
                    <Upload size={24} className="drop-zone-icon" />
                    <div className="drop-zone-text">
                      <span className="drop-title">Drop CV here or click to browse</span>
                      <span className="drop-subtitle">PDF, DOC, or DOCX (max 10MB)</span>
                    </div>
                  </div>
                )}
              </div>
            </div>
          </div>
          {formError && <div className="err-msg">{formError}</div>}
          <div className="upload-actions">
            <button className="btn primary" onClick={submit} disabled={uploading}>
              {uploading ? <Loader2 className="spin" size={15} /> : <Upload size={15} />}
              {uploading ? 'Saving...' : editing ? 'Save changes' : 'Save applicant'}
            </button>
          </div>
        </div>
      )}

      {loading ? (
        <div className="jobs-state">
          <Loader2 className="spin" size={22} />
          <p>Loading applicants...</p>
        </div>
      ) : error ? (
        <div className="jobs-state jobs-error">
          <p>{error}</p>
        </div>
      ) : applicants.length === 0 ? (
        <div className="jobs-state">
          <User size={28} />
          <p>No applicants yet. Add one to upload their CV.</p>
        </div>
      ) : (
        <div className="applicant-list">
          {applicants.map((a) => (
            <div key={a.id} className="applicant-row">
              <div className="applicant-avatar">
                {a.name.trim().charAt(0).toUpperCase() || '?'}
              </div>
              <div className="applicant-info">
                <b>{a.name || a.email}</b>
                <small>{a.email}{a.phone ? ` · ${a.phone}` : ''}</small>
                <small>Added {formatDate(a.updatedAt)}</small>
              </div>
              <div
                className={`applicant-cv ${a.hasCv ? 'draggable' : ''} ${draggingCvId === a.id ? 'is-dragging' : ''}`}
                draggable={a.hasCv}
                onDragStart={(e) => handleCvDragStart(e, a)}
                onDragEnd={handleCvDragEnd}
                title={a.hasCv ? 'Drag CV to another app or tab' : ''}
              >
                {a.hasCv ? (
                  <>
                    <GripVertical size={12} className="drag-handle" />
                    <FileText size={14} />
                    <span>{a.cvName || 'CV'}</span>
                  </>
                ) : (
                  <span className="muted">No CV</span>
                )}
              </div>
              <div className="applicant-actions">
                {a.hasCv && (
                  <a className="row-action" title="Download CV" href={`/api/applicants/${a.id}/cv`}>
                    <Download size={15} />
                  </a>
                )}
                <button className="row-action" title="Edit" onClick={() => openEdit(a)}>
                  <Pencil size={15} />
                </button>
                <button className="row-action danger" title="Delete" onClick={() => remove(a.id)}>
                  <Trash2 size={15} />
                </button>
              </div>
            </div>
          ))}
        </div>
      )}
    </section>
  )
}
