import { useRef, useState, type ChangeEvent, type DragEvent } from 'react'
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { toast } from 'sonner'
import { Paperclip, Upload, Download, Trash2, FileText, Image as ImageIcon, File as FileIcon } from 'lucide-react'
import { api, TOKEN_KEY } from '@/lib/api'
import { getErrorMessage } from '@/lib/apiError'
import { Select } from '@/components/ui/Select'
import { EmptyState } from '@/components/EmptyState'
import type { ContractAttachment } from '@/types/contracts'
import { cn } from '@/lib/cn'

const PurposeLabel: Record<number, string> = {
  1: 'File gốc (draft export)',
  2: 'Bản scan đã ký',
  3: 'Bản scan đã đóng dấu',
  99: 'Khác',
}

const PURPOSES = [1, 2, 3, 99] as const

function fmtSize(n: number) {
  if (n < 1024) return `${n} B`
  if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`
  return `${(n / (1024 * 1024)).toFixed(1)} MB`
}

function iconFor(contentType: string) {
  if (contentType.startsWith('image/')) return ImageIcon
  if (contentType.includes('pdf') || contentType.includes('word') || contentType.includes('document'))
    return FileText
  return FileIcon
}

const BASE_URL = (import.meta.env.VITE_API_BASE_URL ?? '') + '/api'

export function ContractAttachmentsSection({
  contractId,
  attachments,
  canEdit = true,
}: {
  contractId: string
  attachments: ContractAttachment[]
  canEdit?: boolean
}) {
  const qc = useQueryClient()
  const inputRef = useRef<HTMLInputElement>(null)
  const [dragging, setDragging] = useState(false)
  const [purpose, setPurpose] = useState<number>(2)

  const upload = useMutation({
    mutationFn: async (file: File) => {
      const form = new FormData()
      form.append('file', file)
      form.append('purpose', String(purpose))
      const res = await api.post(`/contracts/${contractId}/attachments`, form, {
        headers: { 'Content-Type': 'multipart/form-data' },
      })
      return res.data
    },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['contract', contractId] })
      toast.success('Upload thành công')
    },
    onError: err => toast.error(`Upload lỗi: ${getErrorMessage(err)}`),
  })

  const del = useMutation({
    mutationFn: async (attId: string) => api.delete(`/contracts/${contractId}/attachments/${attId}`),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['contract', contractId] })
      toast.success('Đã xóa')
    },
    onError: err => toast.error(`Xóa lỗi: ${getErrorMessage(err)}`),
  })

  function handleFiles(files: FileList | null) {
    if (!files || files.length === 0) return
    // Upload each file sequentially so the server respects its own rate limits
    for (const f of Array.from(files)) upload.mutate(f)
  }

  function onDrop(e: DragEvent<HTMLDivElement>) {
    e.preventDefault()
    setDragging(false)
    if (!canEdit) return
    handleFiles(e.dataTransfer.files)
  }

  function onPick(e: ChangeEvent<HTMLInputElement>) {
    handleFiles(e.target.files)
    // Reset so same file can be re-picked if needed
    e.target.value = ''
  }

  async function download(att: ContractAttachment) {
    // Blob fetch via fetch API so we can include auth header + trigger browser save
    const token = localStorage.getItem(TOKEN_KEY)
    const res = await fetch(`${BASE_URL}/contracts/${contractId}/attachments/${att.id}/download`, {
      headers: token ? { Authorization: `Bearer ${token}` } : {},
    })
    if (!res.ok) {
      toast.error(`Tải xuống lỗi (HTTP ${res.status})`)
      return
    }
    const blob = await res.blob()
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = att.fileName
    document.body.appendChild(a)
    a.click()
    a.remove()
    URL.revokeObjectURL(url)
  }

  return (
    <section className="rounded-xl border border-slate-200 bg-white p-5 shadow-sm">
      <div className="mb-3 flex items-center justify-between">
        <h2 className="flex items-center gap-2 text-sm font-semibold text-slate-700">
          <Paperclip className="h-4 w-4" />
          Tệp đính kèm ({attachments.length})
        </h2>
        {canEdit && (
          <div className="flex items-center gap-2">
            <Select value={purpose} onChange={e => setPurpose(Number(e.target.value))} className="h-8 w-48 text-xs">
              {PURPOSES.map(p => (
                <option key={p} value={p}>
                  {PurposeLabel[p]}
                </option>
              ))}
            </Select>
          </div>
        )}
      </div>

      {canEdit && (
        <div
          onDragOver={e => {
            e.preventDefault()
            setDragging(true)
          }}
          onDragLeave={() => setDragging(false)}
          onDrop={onDrop}
          onClick={() => inputRef.current?.click()}
          className={cn(
            'mb-3 cursor-pointer rounded-lg border-2 border-dashed px-4 py-6 text-center transition',
            dragging ? 'border-brand-500 bg-brand-50' : 'border-slate-300 bg-slate-50/50 hover:bg-slate-50',
          )}
        >
          <Upload className="mx-auto h-5 w-5 text-slate-400" />
          <div className="mt-2 text-sm font-medium text-slate-600">
            Kéo thả file vào đây hoặc <span className="text-brand-600">chọn file</span>
          </div>
          <div className="mt-0.5 text-xs text-slate-400">PDF / DOCX / XLSX / PNG / JPG · tối đa 20 MB</div>
          <input
            ref={inputRef}
            type="file"
            multiple
            onChange={onPick}
            className="hidden"
            accept=".pdf,.doc,.docx,.xls,.xlsx,.png,.jpg,.jpeg,.webp"
          />
          {upload.isPending && (
            <div className="mt-2 text-xs text-brand-600">Đang upload…</div>
          )}
        </div>
      )}

      {attachments.length === 0 && !canEdit && (
        <EmptyState icon={Paperclip} title="Chưa có tệp đính kèm nào" />
      )}

      {attachments.length > 0 && (
        <ul className="divide-y divide-slate-100">
          {attachments.map(a => {
            const Icon = iconFor(a.contentType)
            return (
              <li key={a.id} className="flex items-center gap-3 py-2.5">
                <div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-md bg-slate-100 text-slate-500">
                  <Icon className="h-4 w-4" />
                </div>
                <div className="min-w-0 flex-1">
                  <div className="truncate text-sm font-medium text-slate-700">{a.fileName}</div>
                  <div className="text-xs text-slate-400">
                    {PurposeLabel[a.purpose] ?? '—'} · {fmtSize(a.fileSize)} ·{' '}
                    {new Date(a.createdAt).toLocaleString('vi-VN', { dateStyle: 'short', timeStyle: 'short' })}
                  </div>
                </div>
                <div className="flex shrink-0 gap-1">
                  <button
                    onClick={() => download(a)}
                    className="flex h-8 w-8 items-center justify-center rounded-md text-slate-500 transition hover:bg-slate-100 hover:text-slate-700"
                    title="Tải xuống"
                  >
                    <Download className="h-4 w-4" />
                  </button>
                  {canEdit && (
                    <button
                      onClick={() => {
                        if (window.confirm(`Xóa tệp "${a.fileName}"?`)) del.mutate(a.id)
                      }}
                      disabled={del.isPending}
                      className="flex h-8 w-8 items-center justify-center rounded-md text-slate-500 transition hover:bg-red-50 hover:text-red-600"
                      title="Xóa"
                    >
                      <Trash2 className="h-4 w-4" />
                    </button>
                  )}
                </div>
              </li>
            )
          })}
        </ul>
      )}

      {canEdit && attachments.length === 0 && (
        <div className="py-2 text-center text-xs text-slate-400">
          Ví dụ: bản scan HĐ đã ký ở phase "Đang in ký", bản đóng dấu ở phase "Đang đóng dấu".
        </div>
      )}
    </section>
  )
}
