import { useState, useRef } from "react"
import mammoth from "mammoth"
import api from '../../lib/api'
import { toast } from "sonner"
import { useMutation, useQueryClient } from "@tanstack/react-query"
import { employeeApi, esignApi } from '../../lib/api-services'
import { useConfirm } from '../../hooks/useConfirm'
import Card from "../../components/ui/Card"
import Button from "../../components/ui/Button"
import { Input, Label, Select } from "../../components/ui/Input"
import { FileText, AlertTriangle, X, Paperclip, Trash2, Info, Download, PenTool } from "lucide-react"

export default function ContractInfo({ employeeId, contracts, hireDate, employee }: { employeeId: string; contracts: any[]; hireDate: string; employee?: any }) {
  const queryClient = useQueryClient()
  const confirm = useConfirm()
  const [showForm, setShowForm] = useState(false)
  const [form, setForm] = useState({ contractType: 'FIXED', signDate: '', startDate: '', endDate: '', contractYears: 3, probationMonths: 0, probationSalary: 0, baseSalary: 0, performanceSalary: 0, signMethod: 'PAPER' as 'PAPER' | 'ELECTRONIC', attachmentUrl: '', attachments: [] as { name: string; url: string }[], electronicContractNo: '', electronicContractUrl: '' })
  const contractFileRef = useRef<HTMLInputElement>(null)
  const supplementFileRefs = useRef<Record<string, HTMLInputElement | null>>({})
  const [previewUrl, setPreviewUrl] = useState<string | null>(null)
  const [previewName, setPreviewName] = useState<string>('附件')
  const [wordHtml, setWordHtml] = useState<string | null>(null)

  const uploadAttachmentMutation = useMutation({
    mutationFn: async ({ contractId, attachmentUrl }: { contractId: string; attachmentUrl: string }) => {
      await api.patch(`/employees/contracts/${contractId}/attachment`, { attachmentUrl })
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['employee-detail'] })
      toast.success('附件已更新')
    },
    onError: () => toast.error('上传失败'),
  })

  const deleteAttachmentMutation = useMutation({
    mutationFn: async ({ contractId, attachmentUrl }: { contractId: string; attachmentUrl: string }) => {
      await api.patch(`/employees/contracts/${contractId}/attachment`, { attachmentUrl })
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['employee-detail'] })
      toast.success('附件已删除')
    },
    onError: () => toast.error('删除失败'),
  })

  const handleDeleteAttachment = async (contractId: string, atts: { name: string; url: string }[], idx: number) => {
    if (!await confirm({ title: '删除附件', message: '确定删除此附件？删除后不可恢复。' })) return
    const newAtts = atts.filter((_, i) => i !== idx)
    deleteAttachmentMutation.mutate({ contractId, attachmentUrl: newAtts.length > 0 ? JSON.stringify(newAtts) : '' })
  }

  const handleSupplementUpload = (e: React.ChangeEvent<HTMLInputElement>, contractId: string, existingAtts: { name: string; url: string }[]) => {
    const files = e.target.files
    if (!files || files.length === 0) return
    const allowedExts = ['.pdf', '.jpg', '.jpeg', '.png', '.heic', '.gif', '.bmp', '.webp', '.doc', '.docx', '.xls', '.xlsx', '.tiff', '.tif']
    const maxSize = 10 * 1024 * 1024
    const validFiles: File[] = []
    for (const file of Array.from(files)) {
      const ext = file.name.toLowerCase().substring(file.name.lastIndexOf('.'))
      if (!allowedExts.includes(ext)) {
        toast.error(`不支持的文件格式: ${file.name}`)
        continue
      }
      if (file.size > maxSize) {
        toast.error(`文件过大: ${file.name}（最大 10MB）`)
        continue
      }
      validFiles.push(file)
    }
    if (validFiles.length === 0) return
    const promises = validFiles.map(file => new Promise<{ name: string; url: string }>((resolve) => {
      const reader = new FileReader()
      reader.onload = (event) => {
        resolve({ name: file.name, url: event.target?.result as string })
      }
      reader.onerror = () => {
        toast.error(`读取文件失败: ${file.name}`)
        resolve({ name: file.name, url: '' })
      }
      reader.readAsDataURL(file)
    }))
    Promise.all(promises).then(atts => {
      const validAtts = atts.filter(a => a.url)
      if (validAtts.length === 0) return
      const merged = [...existingAtts, ...validAtts]
      uploadAttachmentMutation.mutate({ contractId, attachmentUrl: JSON.stringify(merged) })
    })
    e.target.value = ''
  }

  const addContractMutation = useMutation({
    mutationFn: async (data: any) => {
      const res = await employeeApi.addContract({ ...data, employeeId }) as any
      const contractId = res?.data?.id
      if (data.signMethod === 'ELECTRONIC' && contractId) {
        try {
          await esignApi.create({
            contractId,
            employeeId,
            documentTitle: `${data.contractType === 'UNFIXED' ? '无固定期限' : '固定期限'}劳动合同`,
            remark: '合同创建时自动发起',
            scene: 'CONTRACT',
          })
          toast.success('合同已保存，电子签署记录已创建')
        } catch {
          toast.success('合同已保存，电子签署记录创建失败（可稍后手动发起）')
        }
      } else {
        toast.success('合同已保存')
      }
      return res
    },
    onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['roster-profile'] }); queryClient.invalidateQueries({ queryKey: ['esign-records'] }); setShowForm(false) },
  })

  const deleteContractMutation = useMutation({
    mutationFn: (contractId: string) => employeeApi.removeContract(contractId),
    onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['roster-profile'] }); toast.success('合同已作废') },
  })

  const handleContractFileUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files
    if (!files || files.length === 0) return

    const allowedExts = ['.pdf', '.jpg', '.jpeg', '.png', '.heic', '.gif', '.bmp', '.webp', '.doc', '.docx', '.xls', '.xlsx', '.tiff', '.tif']
    const maxSize = 10 * 1024 * 1024

    for (const file of Array.from(files)) {
      const ext = file.name.toLowerCase().substring(file.name.lastIndexOf('.'))
      if (!allowedExts.includes(ext)) {
        toast.error(`不支持的文件格式: ${file.name}`)
        continue
      }
      if (file.size > maxSize) {
        toast.error(`文件过大: ${file.name}（最大 10MB）`)
        continue
      }
      const reader = new FileReader()
      reader.onload = (event) => {
        setForm(prev => ({
          ...prev,
          attachments: [...prev.attachments, { name: file.name, url: event.target?.result as string }],
        }))
      }
      reader.readAsDataURL(file)
    }
    // 清空 input 以便重复选择同一文件
    e.target.value = ''
  }

  const typeMap: Record<string, string> = { FIXED: '固定期限', UNFIXED: '无固定期限', UNSIGNED: '未签订', LABOR: '劳务协议', INTERNSHIP: '实习协议', PARTTIME: '兼职协议', OUTSOURCING: '业务外包' }

  // 按劳动合同法自动判断续签和合同类型建议
  const contractAdvice = (() => {
    if (!contracts?.length) return null
    const fixedContracts = contracts.filter((c: any) => c.contractType === 'FIXED')
    const latestContract = contracts[0]
    const isRenewal = !!latestContract?.endDate
    const renewalCount = (latestContract?.renewalCount || 0)

    // 连续订立二次固定期限劳动合同，第三次应订立无固定期限
    const shouldUnfixed = fixedContracts.length >= 2

    // 连续工作满十年
    const yearsSinceHire = hireDate ? (Date.now() - new Date(hireDate).getTime()) / (365.25 * 24 * 60 * 60 * 1000) : 0
    const shouldUnfixedByTenure = yearsSinceHire >= 10

    if (shouldUnfixed || shouldUnfixedByTenure) {
      return {
        isRenewal,
        renewalCount: isRenewal ? renewalCount + 1 : renewalCount,
        suggestedType: 'UNFIXED',
        reason: shouldUnfixed
          ? `已连续签订${fixedContracts.length}次固定期限合同，按《劳动合同法》第十四条应订立无固定期限合同`
          : `连续工作满${Math.floor(yearsSinceHire)}年，按《劳动合同法》第十四条应订立无固定期限合同`,
      }
    }

    if (isRenewal) {
      return {
        isRenewal: true,
        renewalCount: renewalCount + 1,
        suggestedType: 'FIXED',
        reason: `本次为第${renewalCount + 1}次续签`,
      }
    }

    return null
  })()

  const handleShowForm = () => {
    if (contractAdvice?.suggestedType) {
      setForm({
        ...form,
        contractType: contractAdvice.suggestedType,
        signDate: new Date().toISOString().slice(0, 10),
        startDate: contractAdvice.isRenewal && contracts[0]?.endDate
          ? contracts[0].endDate.toString().slice(0, 10)
          : new Date().toISOString().slice(0, 10),
        endDate: '',
        probationMonths: 0,
        probationSalary: 0,
        baseSalary: employee?.baseSalary != null ? employee.baseSalary : 0,
        performanceSalary: employee?.performanceSalary != null ? employee.performanceSalary : 0,
        signMethod: 'PAPER',
        attachmentUrl: '',
        attachments: [],
        electronicContractNo: '',
        electronicContractUrl: '',
      })
    }
    setShowForm(!showForm)
  }

  return (
    <div className="space-y-3">
      <div className="flex justify-between items-center">
        <h2 className="text-xs font-medium">劳动合同（{contracts?.length || 0}份）</h2>
        <Button size="sm" onClick={handleShowForm}>新增合同</Button>
      </div>

      {contractAdvice && !showForm && (
        <div className="px-3 py-2 rounded-md bg-blue-50 text-blue-700 text-xs flex items-start gap-2">
          <Info className="w-4 h-4 mt-0.5 shrink-0" />
          <span>{contractAdvice.reason}，建议选择「{contractAdvice.suggestedType === 'UNFIXED' ? '无固定期限' : '固定期限'}」</span>
        </div>
      )}

      {showForm && (
        <Card>
          {contractAdvice && (
            <div className="px-3 py-2 mb-3 rounded-md bg-amber-50 text-amber-700 text-xs flex items-start gap-2">
              <AlertTriangle className="w-4 h-4 mt-0.5 shrink-0" />
              <span>{contractAdvice.reason}</span>
            </div>
          )}
          <div className="grid md:grid-cols-2 gap-4">
            <div><Label>合同类型</Label>
              <Select value={form.contractType} onChange={(e) => setForm({ ...form, contractType: e.target.value })}>
                <option value="FIXED">固定期限</option>
                <option value="UNFIXED">无固定期限</option>
              </Select>
            </div>
            <div><Label>签订日期</Label><Input type="date" value={form.signDate} onChange={(e) => setForm({ ...form, signDate: e.target.value })} /></div>
            <div><Label>合同开始日期 *</Label><Input type="date" value={form.startDate} onChange={(e) => setForm({ ...form, startDate: e.target.value })} /></div>
            {form.contractType === 'FIXED' && (
              <div><Label>合同结束日期</Label><Input type="date" value={form.endDate} onChange={(e) => setForm({ ...form, endDate: e.target.value })} /></div>
            )}
            {form.contractType === 'FIXED' && !contractAdvice?.isRenewal && (
              <>
                <div><Label>试用期(月)</Label><Input type="number" value={form.probationMonths} onChange={(e) => setForm({ ...form, probationMonths: parseInt(e.target.value) || 0 })} min={0} max={6} /></div>
                <div><Label>试用期工资</Label><Input type="number" value={form.probationSalary} onChange={(e) => setForm({ ...form, probationSalary: parseInt(e.target.value) || 0 })} /></div>
              </>
            )}
            <div><Label>基本工资</Label><Input type="number" value={form.baseSalary} onChange={(e) => setForm({ ...form, baseSalary: parseFloat(e.target.value) || 0 })} placeholder="元/月" /></div>
            <div><Label>绩效工资</Label><Input type="number" value={form.performanceSalary} onChange={(e) => setForm({ ...form, performanceSalary: parseFloat(e.target.value) || 0 })} placeholder="可为0" /></div>
            <div className="md:col-span-2 border-t pt-3">
              <Label>签订方式</Label>
              <Select value={form.signMethod} onChange={(e) => setForm({ ...form, signMethod: e.target.value as 'PAPER' | 'ELECTRONIC' })}>
                <option value="PAPER">纸质签署</option>
                <option value="ELECTRONIC">电子签署</option>
              </Select>
            </div>
            {form.signMethod === 'PAPER' && (
              <div className="md:col-span-2">
                <Label>合同附件（可选，保存后可再补充上传）</Label>
                <input ref={contractFileRef} type="file" multiple className="hidden" onChange={handleContractFileUpload} />
                <div className="flex items-center gap-2">
                  <Button size="sm" variant="secondary" onClick={() => contractFileRef.current?.click()}>
                    <Paperclip className="w-4 h-4 mr-1" />上传附件
                  </Button>
                  {form.attachments.length > 0 && <span className="text-xs text-gray-500">{form.attachments.length} 个文件</span>}
                </div>
                {form.attachments.length > 0 && (
                  <div className="mt-2 space-y-1">
                    {form.attachments.map((att, idx) => (
                      <div key={idx} className="flex items-center justify-between text-xs bg-gray-50 rounded px-2 py-1">
                        <button type="button" onClick={() => setPreviewUrl(att.url)} className="text-primary hover:underline flex items-center gap-1 truncate">
                          <Paperclip className="w-3 h-3 shrink-0" />{att.name}
                        </button>
                        <button type="button" onClick={() => setForm(prev => ({ ...prev, attachments: prev.attachments.filter((_, i) => i !== idx) }))} className="text-danger hover:underline ml-2 shrink-0">
                          <X className="w-3 h-3" />
                        </button>
                      </div>
                    ))}
                  </div>
                )}
                <p className="text-xs text-gray-400 mt-1">支持 PDF、JPG、PNG、HEIC、GIF、BMP、WebP、TIFF、Word、Excel 等格式，每个文件最大 10MB</p>
              </div>
            )}
            {form.signMethod === 'ELECTRONIC' && (
              <div className="md:col-span-2">
                <div className="px-3 py-2 rounded-md bg-blue-50 text-blue-700 text-xs flex items-start gap-2">
                  <PenTool className="w-4 h-4 mt-0.5 shrink-0" />
                  <span>保存合同后将自动创建电子签署记录，对接易签宝后系统会自动生成签署链接并发送给员工。当前为框架预留阶段，签署记录创建后可在「电子签署」页面查看。</span>
                </div>
              </div>
            )}
            <div className="md:col-span-2 flex gap-2">
              <Button onClick={() => {
                const payload = {
                  ...form,
                  attachmentUrl: form.attachments.length > 0 ? JSON.stringify(form.attachments) : '',
                  signDate: form.signDate ? new Date(form.signDate).toISOString() : null,
                  startDate: new Date(form.startDate).toISOString(),
                  endDate: form.endDate ? new Date(form.endDate).toISOString() : null,
                }
                addContractMutation.mutate(payload)
              }} disabled={
                addContractMutation.isPending || !form.startDate
              }>
                {addContractMutation.isPending ? '保存中...' : '保存'}
              </Button>
              <Button variant="secondary" onClick={() => setShowForm(false)}>取消</Button>
            </div>
          </div>
        </Card>
      )}

      {!contracts?.length ? (
        <Card><div className="text-center py-8 text-gray-400">暂无合同记录</div></Card>
      ) : contracts.map((c) => (
        <Card key={c.id}>
          <div className="flex items-start justify-between">
            <div className="grid md:grid-cols-3 gap-x-6 gap-y-3 flex-1 text-xs">
              <div className="flex justify-between"><span className="text-gray-500 shrink-0">合同类型</span><span className="font-medium text-right truncate ml-2">{typeMap[c.contractType] || c.contractType}</span></div>
              <div className="flex justify-between"><span className="text-gray-500 shrink-0">签订日期</span><span className="font-medium text-right truncate ml-2">{c.signDate ? c.signDate.toString().slice(0, 10) : '未签订'}</span></div>
              <div className="flex justify-between"><span className="text-gray-500 shrink-0">合同开始</span><span className="font-medium text-right truncate ml-2">{c.startDate?.toString().slice(0, 10)}</span></div>
              <div className="flex justify-between"><span className="text-gray-500 shrink-0">合同结束</span><span className="font-medium text-right truncate ml-2">{c.endDate ? c.endDate.toString().slice(0, 10) : '无固定期限'}</span></div>
              <div className="flex justify-between"><span className="text-gray-500 shrink-0">合同期限</span><span className="font-medium text-right truncate ml-2">{c.contractYears}年</span></div>
              <div className="flex justify-between"><span className="text-gray-500 shrink-0">基本工资</span><span className="font-medium text-right truncate ml-2">¥{c.baseSalary || 0}/月</span></div>
              <div className="flex justify-between"><span className="text-gray-500 shrink-0">绩效工资</span><span className="font-medium text-right truncate ml-2">¥{c.performanceSalary || 0}/月</span></div>
              <div className="flex justify-between"><span className="text-gray-500 shrink-0">试用期</span><span className="font-medium text-right truncate ml-2">{c.probationMonths}个月（¥{c.probationSalary}）</span></div>
              <div className="flex justify-between"><span className="text-gray-500 shrink-0">签订方式</span><span className="font-medium text-right truncate ml-2">{c.signMethod === 'PAPER' ? '纸质' : '电子'}</span></div>
              <div className="flex justify-between"><span className="text-gray-500 shrink-0">续签次数</span><span className="font-medium text-right truncate ml-2">{c.renewalCount}</span></div>
              {c.signMethod === 'PAPER' && (
                <div className="md:col-span-3">
                  <span className="text-gray-500">合同附件</span>
                  {(() => {
                    let atts: { name: string; url: string }[] = []
                    try {
                      if (!c.attachmentUrl) throw new Error('empty')
                      const parsed = JSON.parse(c.attachmentUrl)
                      atts = Array.isArray(parsed) ? parsed : [{ name: '附件', url: c.attachmentUrl }]
                    } catch {
                      if (c.attachmentUrl) {
                        const mime = c.attachmentUrl.match(/data:(.*?);/)?.[1] || ''
                        const ext = mime.split('/')[1] || '文件'
                        atts = [{ name: `附件.${ext}`, url: c.attachmentUrl }]
                      }
                    }
                    return (
                      <div className="mt-1 space-y-1">
                        {atts.length === 0 && <span className="text-gray-400 ml-2">未上传</span>}
                        {atts.map((att, idx) => (
                          <div key={idx} className="flex items-center justify-between text-xs bg-gray-50 rounded px-2 py-1">
                            <button onClick={() => { setPreviewName(att.name); setPreviewUrl(att.url) }} className="text-primary hover:underline flex items-center gap-1 truncate">
                              <Paperclip className="w-3 h-3 shrink-0" />{att.name}
                            </button>
                            <div className="flex items-center gap-1 ml-2 shrink-0">
                              <button
                                type="button"
                                className="text-gray-400 hover:text-primary"
                                title="下载附件"
                                onClick={() => {
                                  const dataToBlobUrl = (dataUrl: string) => {
                                    try {
                                      const arr = dataUrl.split(',')
                                      const mime = arr[0].match(/:(.*?);/)?.[1] || 'application/octet-stream'
                                      const bstr = atob(arr[1])
                                      const u8 = new Uint8Array(bstr.length)
                                      for (let i = 0; i < bstr.length; i++) u8[i] = bstr.charCodeAt(i)
                                      return URL.createObjectURL(new Blob([u8], { type: mime }))
                                    } catch { return dataUrl }
                                  }
                                  const blobUrl = att.url.startsWith('data:') ? dataToBlobUrl(att.url) : att.url
                                  const a = document.createElement('a')
                                  a.href = blobUrl
                                  a.download = att.name
                                  a.click()
                                  if (blobUrl !== att.url) URL.revokeObjectURL(blobUrl)
                                }}
                              >
                                <Download className="w-3 h-3" />
                              </button>
                              <button
                                type="button"
                                className="text-gray-400 hover:text-danger"
                                title="删除附件"
                                disabled={deleteAttachmentMutation.isPending}
                                onClick={() => handleDeleteAttachment(c.id, atts, idx)}
                              >
                                <Trash2 className="w-3 h-3" />
                              </button>
                            </div>
                          </div>
                        ))}
                        <input id={`contract-file-${c.id}`} type="file" multiple className="hidden" onChange={(e) => handleSupplementUpload(e, c.id, atts)} />
                        <button type="button" onClick={() => document.getElementById(`contract-file-${c.id}`)?.click()} disabled={uploadAttachmentMutation.isPending} className="inline-flex items-center justify-center font-medium rounded-md transition-colors bg-gray-100 text-gray-700 hover:bg-gray-200 px-3 py-1.5 text-xs">
                          <Paperclip className="w-3 h-3 mr-1" />{atts.length > 0 ? '补充上传' : '上传附件'}
                        </button>
                      </div>
                    )
                  })()}
                </div>
              )}
              {c.signMethod === 'ELECTRONIC' && (
                <div className="flex justify-between md:col-span-3">
                  <span className="text-gray-500">签署方式</span>
                  <span className="text-primary flex items-center gap-1 text-xs">
                    <PenTool className="w-3 h-3" />电子签署（记录已创建，请在「电子签署」页面查看进度）
                  </span>
                </div>
              )}
            </div>
            <button
              onClick={async () => { if (await confirm({ title: '作废合同', message: '确定作废此合同记录？作废后记录将保留但不再生效。' })) deleteContractMutation.mutate(c.id) }}
              className="text-gray-400 hover:text-danger shrink-0 ml-2 mt-1"
              title="作废合同"
            >
              <Trash2 className="w-4 h-4" />
            </button>
          </div>
        </Card>
      ))}

      {/* 附件预览弹窗 */}
      {previewUrl && (() => {
        // 将 data URL 转为 blob URL，解决浏览器阻止 iframe 加载 data URL 的问题
        const dataToBlobUrl = (dataUrl: string) => {
          try {
            const arr = dataUrl.split(',')
            const mime = arr[0].match(/:(.*?);/)?.[1] || 'application/octet-stream'
            const bstr = atob(arr[1])
            const u8 = new Uint8Array(bstr.length)
            for (let i = 0; i < bstr.length; i++) u8[i] = bstr.charCodeAt(i)
            return URL.createObjectURL(new Blob([u8], { type: mime }))
          } catch { return dataUrl }
        }
        const blobUrl = previewUrl.startsWith('data:') ? dataToBlobUrl(previewUrl) : previewUrl
        const mime = previewUrl.startsWith('data:') ? previewUrl.match(/data:(.*?);/)?.[1] || '' : ''
        const isImage = mime.startsWith('image/')
        const isPdf = mime === 'application/pdf'
        const isWord = mime === 'application/msword' || mime === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' || previewName.endsWith('.doc') || previewName.endsWith('.docx')

        // 如果是 Word 文件且尚未转换，异步转换
        if (isWord && !wordHtml) {
          fetch(blobUrl)
            .then(r => r.arrayBuffer())
            .then(buf => mammoth.convertToHtml({ arrayBuffer: buf }))
            .then(result => setWordHtml(result.value))
            .catch(() => setWordHtml('<p style="text-align:center;color:#999;">Word 文件转换失败，请下载查看</p>'))
        }

        const closePreview = () => {
          if (blobUrl !== previewUrl) URL.revokeObjectURL(blobUrl)
          setPreviewUrl(null)
          setWordHtml(null)
        }

        return (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50" onClick={closePreview}>
          <div className="bg-white rounded-lg shadow-xl max-w-4xl w-full h-[90vh] flex flex-col" onClick={e => e.stopPropagation()}>
            <div className="flex items-center justify-between px-4 py-2 border-b">
              <span className="text-sm font-medium">附件预览 - {previewName}</span>
              <div className="flex items-center gap-2">
                <button type="button" onClick={() => {
                  const a = document.createElement('a')
                  a.href = blobUrl
                  a.download = previewName
                  document.body.appendChild(a)
                  a.click()
                  document.body.removeChild(a)
                }} className="text-xs text-primary hover:underline flex items-center gap-1">
                  <Download className="w-3 h-3" />下载
                </button>
                <button onClick={closePreview} className="text-gray-400 hover:text-gray-600">
                  <X className="w-4 h-4" />
                </button>
              </div>
            </div>
            <div className="flex-1 overflow-auto flex items-center justify-center p-4">
              {isImage ? (
                <img src={blobUrl} alt="附件预览" className="max-w-full max-h-full object-contain" />
              ) : isPdf ? (
                <embed src={blobUrl} type="application/pdf" className="w-full h-full" />
              ) : isWord ? (
                wordHtml ? (
                  <div className="prose prose-sm max-w-none w-full" dangerouslySetInnerHTML={{ __html: wordHtml }} />
                ) : (
                  <div className="text-center space-y-3">
                    <div className="animate-spin w-8 h-8 border-2 border-primary border-t-transparent rounded-full mx-auto" />
                    <p className="text-sm text-gray-500">正在转换 Word 文档...</p>
                  </div>
                )
              ) : (
                <div className="text-center space-y-3">
                  <FileText className="w-12 h-12 text-gray-300 mx-auto" />
                  <p className="text-sm text-gray-500">此文件格式不支持在线预览</p>
                  <button type="button" onClick={() => {
                    const a = document.createElement('a')
                    a.href = blobUrl
                    a.download = previewName
                    document.body.appendChild(a)
                    a.click()
                    document.body.removeChild(a)
                  }} className="inline-flex items-center gap-1 text-sm text-primary hover:underline">
                    <Download className="w-4 h-4" />点击下载查看
                  </button>
                </div>
              )}
            </div>
          </div>
        </div>
        )
      })()}
    </div>
  )
}
