import { useEffect, useMemo, useRef, useState } from 'react';

import type { ExamClient, ExamModalTab } from '../../data/mockData';
import type {
  CustomerAppointmentInfo,
  CustomerExamAddItem,
  CustomerInfo,
  PhysicalExamProgressItem,
} from '../../api';
import { getCustomerDetail, getPhysicalExamProgressDetail, signInMedicalExamCenter, getTongyishuPdf } from '../../api';
import { Button, Input } from '../ui';

interface ExamModalProps {
  client: ExamClient;
  tab: ExamModalTab;
  onTabChange: (key: ExamModalTab) => void;
  onClose: () => void;
}

export const ExamModal = ({ client, tab, onTabChange, onClose }: ExamModalProps) => {
  const tabs: { key: ExamModalTab; label: string }[] = [
    { key: 'detail', label: '详情' },
    { key: 'sign', label: '签到' },
    { key: 'addon', label: '加项' },
    { key: 'print', label: '打印导检单' },
    { key: 'delivery', label: '报告寄送' },
  ];

  const signDone = client.signStatus === '已登记' || client.checkedItems.includes('签到');
  const addonDone = (client.addonCount || 0) > 0;
  const printDone = !!client.guidePrinted;
  const deliveryDone = !!client.deliveryDone;

  const tabDone: Record<ExamModalTab, boolean> = {
    detail: false,
    sign: signDone,
    addon: addonDone,
    print: printDone,
    delivery: deliveryDone,
  };

  const handleDoubleClick = (e: React.MouseEvent) => {
    e.preventDefault();
    e.stopPropagation();
  };

  const handleTouchStart = (e: React.TouchEvent) => {
    if (e.touches.length > 1) {
      e.preventDefault();
    }
  };

  const [detailLoading, setDetailLoading] = useState(false);
  const [customerInfo, setCustomerInfo] = useState<CustomerInfo | null>(null);
  const [appointmentInfo, setAppointmentInfo] = useState<CustomerAppointmentInfo | null>(null);
  const [addItemInfoList, setAddItemInfoList] = useState<CustomerExamAddItem[] | null>(null);
  const [progressList, setProgressList] = useState<PhysicalExamProgressItem[] | null>(null);

  useEffect(() => {
    const physical_exam_id = Number(client.id);
    if (!physical_exam_id) return;
    setDetailLoading(true);
    Promise.all([
      getCustomerDetail({ physical_exam_id }),
      getPhysicalExamProgressDetail({ physical_exam_id }),
    ])
      .then(([detailRes, progressRes]) => {
        setCustomerInfo(detailRes.Data?.customerInfo ?? null);
        setAppointmentInfo(detailRes.Data?.appointmentInfo ?? null);
        setAddItemInfoList(detailRes.Data?.addItemInfoList ?? null);
        setProgressList(progressRes.Data?.examProgressesList ?? null);
      })
      .catch((err) => {
        console.error('获取客户详情/进度失败', err);
      })
      .finally(() => setDetailLoading(false));
  }, [client.id]);

  return (
    <div
      className='fixed inset-0 z-40 flex items-center justify-center bg-black/50'
      style={{ touchAction: 'none' }}
      onDoubleClick={handleDoubleClick}
      onTouchStart={handleTouchStart}
    >
      <div
        className='w-[960px] max-w-[95vw] max-h-[95vh] bg-white rounded-2xl shadow-xl overflow-hidden text-sm'
        style={{ touchAction: 'none' }}
        onDoubleClick={handleDoubleClick}
        onTouchStart={handleTouchStart}
      >

        {/* Header 区域：增加了内边距 padding */}
        <div className='px-8 pt-6 pb-2'>
          <div className='flex items-center justify-between'>
            {/* 左侧：姓名 + VIP + 体检号 */}
            <div className='flex items-end gap-3'>
              <span className='text-2xl font-bold text-gray-900 leading-none'>
                {client.name}
              </span>
              {/* VIP 徽章样式优化：紫色背景 + 左右内边距 */}
              <span className='inline-flex items-center justify-center bg-indigo-100 text-indigo-600 text-[11px] font-bold px-2 py-0.5 rounded h-5 align-bottom'>
                VIP
              </span>
              <span className='text-sm text-gray-400 ml-1 leading-none mb-0.5'>
                体检号：{client.id}
              </span>
            </div>

            {/* 右侧：仅保留关闭按钮 */}
            <button
              className='text-gray-400 hover:text-gray-600 transition-colors text-sm'
              onClick={onClose}
            >
              关闭
            </button>
          </div>
        </div>

        {/* Tabs 区域 */}
        <div className='px-8 py-4 flex items-center justify-between'>
          <div className='flex items-center gap-3'>
            {tabs.map((t) => {
              const isActive = tab === t.key;
              const isDone = tabDone[t.key];
              return (
                <button
                  key={t.key}
                  onClick={() => onTabChange(t.key)}
                  // 样式修改：rounded-full (完全圆角), border 颜色调整, 增加选中时的阴影
                  className={`px-5 py-2 rounded-2xl border text-sm transition-all duration-200 ${isActive
                    ? 'bg-blue-600 text-white border-blue-600 shadow-md shadow-blue-200'
                    : isDone
                      ? 'bg-gray-50 text-gray-400 border-gray-100'
                      : 'bg-white text-gray-600 border-gray-200 hover:border-gray-300'
                    }`}
                >
                  {t.label}
                  {/* 这里保留了原有逻辑，但微调了样式 */}
                  {t.key === 'addon' && (client.addonCount || 0) > 0 && (
                    <span className={`text-xs ${isActive ? 'text-blue-100' : 'text-gray-400'}`}>
                      ({client.addonCount})
                    </span>
                  )}
                  {((t.key === 'sign' && signDone) || (t.key === 'print' && printDone)) && (
                    <span className=''></span>
                  )}
                </button>
              );
            })}
          </div>

          {/* 按钮部分：将原本在 Tab 右侧的任何操作可以放这里，或者留空 */}
        </div>

        <div className='px-4 py-4 bg-gray-50/60'>
          {tab === 'detail' && (
            <ExamDetailInfo
              client={client}
              customerInfo={customerInfo}
              appointmentInfo={appointmentInfo}
              addItemInfoList={addItemInfoList}
              progressList={progressList}
              loading={detailLoading}
            />
          )}
          {tab === 'sign' && <ExamSignPanel />}
          {tab === 'addon' && <ExamAddonPanel client={client} />}
          {tab === 'print' && <ExamPrintPanel client={client} />}
          {tab === 'delivery' && <ExamDeliveryPanel client={client} />}
        </div>

      </div>
    </div>
  );
};

const ExamSignPanel = () => {
  const [idNo, setIdNo] = useState('');
  const [ocrLoading, setOcrLoading] = useState(false);
  const [signLoading, setSignLoading] = useState(false);
  const [message, setMessage] = useState<string | null>(null);
  const fileInputRef = useRef<HTMLInputElement | null>(null);

  const handlePickFile = () => {
    fileInputRef.current?.click();
  };

  const mockOcr = async (file: File) => {
    // 简单模拟 OCR：提取文件名中的数字，或返回示例身份证
    const match = file.name.match(/\d{6,18}/);
    await new Promise((r) => setTimeout(r, 600));
    return match?.[0] || '440101199001010010';
  };

  const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    setOcrLoading(true);
    setMessage(null);
    try {
      const ocrId = await mockOcr(file);
      setIdNo(ocrId);
    } catch (err) {
      console.error(err);
      setMessage('OCR 识别失败，请重试或手动输入');
    } finally {
      setOcrLoading(false);
      e.target.value = '';
    }
  };

  const handleSign = async () => {
    const trimmed = idNo.trim();
    if (!trimmed) {
      setMessage('请输入身份证号');
      return;
    }
    setSignLoading(true);
    setMessage(null);
    try {
      const res = await signInMedicalExamCenter({ id_no: trimmed });
      const ok = res.Status === 200 && res.Data?.is_success === 0;
      setMessage(ok ? '签到成功' : res.Message || '签到失败');
    } catch (err) {
      console.error(err);
      setMessage('签到请求失败，请稍后重试');
    } finally {
      setSignLoading(false);
    }
  };

  return (
    <div className='grid grid-cols-2 gap-4 text-sm'>
      <div className='p-4 rounded-2xl border bg-gray-50/60 flex flex-col gap-3'>
        <div className='font-medium'>身份证扫描与签到</div>
        <div className='text-xs text-gray-500'>
          支持扫描身份证识别证号，确认后再点击签到。
        </div>
        <div className='flex items-center gap-3'>
          <Button className='py-1.5 px-3' onClick={handlePickFile} disabled={ocrLoading || signLoading}>
            {ocrLoading ? '识别中...' : '扫描身份证'}
          </Button>
          <input
            ref={fileInputRef}
            type='file'
            accept='image/*'
            className='hidden'
            onChange={handleFileChange}
          />
          <Input
            placeholder='身份证号'
            value={idNo}
            onChange={(e) => setIdNo(e.target.value)}
            className='flex-1'
          />
          <Button
            className='py-1.5 px-4'
            onClick={handleSign}
            disabled={signLoading}
          >
            {signLoading ? '签到中...' : '签到'}
          </Button>
        </div>
        {message && <div className='text-xs text-gray-600'>{message}</div>}
        <div className='text-[11px] text-gray-400'>如识别不准，可手动修改后再签到。</div>
      </div>
      <div className='p-4 rounded-2xl border bg-gray-50/60 flex flex-col gap-3'>
        <div className='font-medium'>体检知情同意书</div>
        <div className='text-xs text-gray-500'>点击后弹出知情同意书全文及签名区域，签署完成后回到签到页面。</div>
        <Button className='py-1.5 px-3'>打开知情同意书并签署</Button>
      </div>
    </div>
  );
};

interface AddonTag {
  title: string;
  type: 1 | 2 | 3 | 4; // 1: 热门(红), 2: 普通(灰), 3: 医生推荐(蓝), 4: 折扣信息
}

interface AddonItem {
  id?: string;
  name: string;
  paid?: boolean;
  tags?: AddonTag[];
  originalPrice?: string;
  currentPrice?: string;
  price?: number; // 兼容 addonOptions 结构
}

const ExamAddonPanel = ({ client }: { client: ExamClient }) => {
  // 从 client 获取加项选项数据
  const addonOptions = (client['addonOptions' as keyof ExamClient] as AddonItem[] | undefined) || [];
  const addonSummary = (client['addonSummary' as keyof ExamClient] as AddonItem[] | undefined) || [];

  // 合并数据，优先使用 addonOptions，如果没有则使用 addonSummary
  const allAddons: AddonItem[] = addonOptions.length > 0
    ? addonOptions.map(item => ({
      id: item.id || `addon_${item.name}`,
      name: item.name,
      paid: item.paid || false,
      tags: item.tags || [],
      originalPrice: item.originalPrice || (item.price ? item.price.toFixed(2) : '0.00'),
      currentPrice: item.currentPrice || (item.price ? item.price.toFixed(2) : '0.00'),
    }))
    : addonSummary;

  const [selectedIds, setSelectedIds] = useState<Set<string>>(
    new Set(allAddons.filter(item => item.paid).map(item => item.id || item.name))
  );

  const maxSelect = 15;
  const selectedCount = selectedIds.size;

  const [addonSearch, setAddonSearch] = useState('');

  const filteredAddons = addonSearch.trim()
    ? allAddons.filter(item =>
      item.name.toLowerCase().includes(addonSearch.toLowerCase())
    )
    : allAddons;

  const toggleSelect = (id: string) => {
    if (selectedIds.has(id)) {
      setSelectedIds(prev => {
        const next = new Set(prev);
        next.delete(id);
        return next;
      });
    } else {
      if (selectedCount < maxSelect) {
        setSelectedIds(prev => new Set(prev).add(id));
      }
    }
  };

  // 计算价格汇总
  const selectedItems = allAddons.filter(item => selectedIds.has(item.id || item.name));
  const totalOriginal = selectedItems.reduce((sum, item) => {
    return sum + parseFloat(item.originalPrice || item.currentPrice || '0');
  }, 0);
  const totalCurrent = selectedItems.reduce((sum, item) => {
    return sum + parseFloat(item.currentPrice || item.originalPrice || '0');
  }, 0);
  const discount = totalOriginal - totalCurrent;

  // 获取标签样式
  const getTagStyle = (tag: AddonTag) => {
    switch (tag.type) {
      case 1: // 热门
        return 'bg-[#FDF0F0] text-[#BC4845]';
      case 3: // 医生推荐
        return 'bg-[#ECF0FF] text-[#6A6AE5]';
      case 4: // 折扣信息
        return 'bg-[#4C5460] text-[#F1F2F5]';
      default: // 2: 普通
        return 'bg-[#F1F2F5] text-[#464E5B]';
    }
  };

  // 获取折扣信息文字（从 tags 中提取 type 4 的标签，或计算折扣）
  const getDiscountText = (item: AddonItem) => {
    const discountTag = item.tags?.find(t => t.type === 4);
    if (discountTag) return discountTag.title;

    const orig = parseFloat(item.originalPrice || '0');
    const curr = parseFloat(item.currentPrice || '0');
    if (orig > 0 && curr < orig) {
      const percent = Math.round((curr / orig) * 100);
      return `渠道 ${percent} 折`;
    }
    return '渠道价';
  };

  return (
    <div className='space-y-4'>
      {/* 标题和说明 */}
      <div>
        <div className='flex items-center justify-between mb-2 gap-3'>
          <h3 className='text-lg font-semibold text-gray-900'>体检套餐加项选择</h3>
          <div className='w-[260px]'>
            <Input
              placeholder='搜索 加项名称'
              value={addonSearch}
              onChange={(e) => setAddonSearch(e.target.value)}
              className='text-sm'
            />
          </div>
        </div>
        <div className='text-xs text-gray-600 space-y-1'>
          <div>最多可选 {maxSelect} 项 · 一排 5 个</div>
          <div>已勾选 {selectedCount} 项,自费加项费用按渠道折扣价结算。</div>
        </div>
      </div>

      {/* 加项网格 */}
      <div className='grid grid-cols-5 gap-3 min-h-[142px]'>
        {filteredAddons.map((item) => {
          const id = item.id || item.name;
          const isSelected = selectedIds.has(id);
          const origPrice = parseFloat(item.originalPrice || '0');
          const currPrice = parseFloat(item.currentPrice || '0');

          return (
            <div
              key={id}
              className={`border rounded-lg p-3 cursor-pointer transition-all'
                }`}
              onClick={() => toggleSelect(id)}
            >
              {/* 复选框 */}
              <div className='flex items-start gap-2 mb-2'>
                <input
                  type='checkbox'
                  checked={isSelected}
                  onChange={() => toggleSelect(id)}
                  onClick={(e) => e.stopPropagation()}
                  className='mt-0.5 w-4 h-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500'
                />
                <div className='flex-1 min-w-0'>
                  {/* 项目名称 */}
                  <div className='font-semibold text-[14px] text-gray-900 mb-1'>{item.name}</div>

                  {/* 标签 */}
                  {item.tags && item.tags.length > 0 && (
                    <div className='flex flex-wrap gap-1 mb-2'>
                      {item.tags
                        .filter(t => t.type !== 4) // 折扣信息单独显示
                        .map((tag, idx) => (
                          <span
                            key={idx}
                            className={`text-[10px] px-2 rounded-full ${getTagStyle(tag)}`}
                          >
                            {tag.title}
                          </span>
                        ))}
                    </div>
                  )}
                </div>
              </div>

              {/* 价格信息 */}
              <div className='mt-2'>
                <div className='flex flex-col'>
                  {origPrice > 0 && origPrice > currPrice && (
                    <span className='text-xs text-gray-400 line-through'>¥{origPrice.toFixed(0)}</span>
                  )}
                  <div className='flex items-center justify-between gap-2'>
                    <span className='text-[14px] font-bold text-red-600'>¥{currPrice.toFixed(0)}</span>
                    <span className={`text-[10px] px-2 rounded-full bg-[#EAFCF1] text-[#447955] whitespace-nowrap`}>{getDiscountText(item)}</span>
                  </div>
                </div>
              </div>
            </div>
          );
        })}
      </div>

      {/* 底部汇总和支付 */}
      <div className='border-t pt-4 mt-6 flex items-center justify-between'>
        <div className='space-y-1 text-sm'>
          <div className='text-gray-600'>
            加项原价合计: <span className='text-gray-900'>¥{totalOriginal.toFixed(0)}</span>
          </div>
          <div className='text-gray-600'>
            渠道折扣价: <span className='text-xl font-bold text-red-600'>¥{totalCurrent.toFixed(0)}</span>
            {discount > 0 && (
              <span className='text-gray-500 ml-1'>已优惠 ¥{discount.toFixed(0)}</span>
            )}
          </div>
          <div className='text-xs text-gray-500'>结算方式: 个人支付 (微信 / 支付宝)</div>
        </div>
        <Button
          className='bg-[#269745] hover:bg-[#269745]/80 rounded-3xl text-white px-6 py-3 text-base font-medium'
          disabled={selectedCount === 0}
        >
          确认支付 ¥{totalCurrent.toFixed(0)}
        </Button>
      </div>
    </div>
  );
};

const ExamDetailInfo = ({
  client,
  customerInfo,
  appointmentInfo,
  addItemInfoList,
  progressList,
  loading,
}: {
  client: ExamClient;
  customerInfo: CustomerInfo | null;
  appointmentInfo: CustomerAppointmentInfo | null;
  addItemInfoList: CustomerExamAddItem[] | null;
  progressList: PhysicalExamProgressItem[] | null;
  loading: boolean;
}) => {
  const basePhone = customerInfo?.phone || (client['mobile' as keyof ExamClient] as string | undefined) || '';
  const baseMarital =
    customerInfo?.patient_marital_status_name ||
    (client['maritalStatus' as keyof ExamClient] as string | undefined) ||
    '—';
  const [phone, setPhone] = useState(basePhone || '—');
  const [marital, setMarital] = useState(baseMarital);
  const [phoneEditing, setPhoneEditing] = useState(false);
  const [maritalEditing, setMaritalEditing] = useState(false);

  const customerChannel = client.customerType === '团客' ? '团体客户' : '散客客户';
  const familyDoctor = customerInfo?.family_doctor_name || (client['familyDoctor' as keyof ExamClient] as string | undefined) || '—';
  const groupTag = client['groupTag' as keyof ExamClient] || (client.customerType === '团客' ? '团检' : '—');
  const bookingTime = appointmentInfo?.appointment_time || (client['bookingTime' as keyof ExamClient] || '—');
  const signTime = appointmentInfo?.sign_in_time || (client['signTime' as keyof ExamClient] || '—');
  const addonSummary =
    addItemInfoList && addItemInfoList.length > 0
      ? addItemInfoList.map((i) => `${i.dept_name ?? ''} ${i.combination_name ?? ''}`.trim()).join('、')
      : client['addonSummary' as keyof ExamClient] || '—';

  const progressGroups = useMemo(() => {
    const checked: string[] = [];
    const abandoned: string[] = [];
    const pending: string[] = [];
    const deferred: string[] = [];
    (progressList || []).forEach((p) => {
      const name = p.project_name || p.department_name || '项目';
      switch (p.exam_status) {
        case 1:
          checked.push(name);
          break;
        case 2:
          abandoned.push(name);
          break;
        case 4:
          deferred.push(name);
          break;
        default:
          pending.push(name);
      }
    });
    return { checked, abandoned, pending, deferred };
  }, [progressList]);

  return (
    <div className='space-y-4 text-sm'>
      <div className='flex items-center gap-4'>
        <div className='w-14 h-14 rounded-full bg-gray-200 flex-shrink-0 overflow-hidden'>
          <div className='w-full h-full rounded-full bg-gray-300 flex items-center justify-center text-[10px] text-gray-500'>
            头像
          </div>
        </div>
        <div className='text-xs text-gray-500'>
          {loading ? '加载中…' : '基础信息：头像、姓名、证件号、手机号等（点击图标可进行编辑）'}
        </div>
      </div>

      <div className='space-y-2 text-xs text-gray-700'>
        <div className='font-medium text-gray-900'>基础信息</div>
        <div className='grid grid-cols-2 gap-x-8 gap-y-1'>
          <div>
            姓名：<span className='text-gray-900'>{customerInfo?.customer_name || client.name}</span>
          </div>
          <div>
            证件号：<span className='text-gray-900'>{customerInfo?.id_no || '—'}</span>
          </div>
          <div className='flex items-center'>
            <span>手机号：</span>
            {!phoneEditing ? (
              <span className='text-gray-900 flex items-center'>
                {phone}
                <button className='ml-1 text-blue-500 text-[11px] hover:underline' onClick={() => setPhoneEditing(true)}>
                  ✏️ 编辑
                </button>
              </span>
            ) : (
              <span className='flex items-center gap-1'>
                <input
                  className='w-28 rounded-xl border px-2 py-0.5 text-[11px] outline-none'
                  value={phone}
                  onChange={(e) => setPhone(e.target.value)}
                />
                <button className='px-2 py-0.5 rounded-xl border text-[11px]' onClick={() => setPhoneEditing(false)}>
                  保存
                </button>
              </span>
            )}
          </div>
          <div>
            性别/年龄：
            <span className='text-gray-900'>
              {customerInfo?.gender_name || client.gender} / {client.age}
            </span>
          </div>
          <div>
            客户级别：<span className='text-gray-900'>{client.level}</span>
          </div>
          <div>
            所属渠道：<span className='text-gray-900'>{customerChannel}</span>
          </div>
          <div className='flex items-center'>
            <span>婚姻状况：</span>
            {!maritalEditing ? (
              <span className='text-gray-900 flex items-center'>
                {marital}
                <button className='ml-1 text-blue-500 text-[11px] hover:underline' onClick={() => setMaritalEditing(true)}>
                  ✏️ 编辑
                </button>
              </span>
            ) : (
              <span className='flex items-center gap-1'>
                <input
                  className='w-20 rounded-xl border px-2 py-0.5 text-[11px] outline-none'
                  value={marital}
                  onChange={(e) => setMarital(e.target.value)}
                />
                <button className='px-2 py-0.5 rounded-xl border text-[11px]' onClick={() => setMaritalEditing(false)}>
                  保存
                </button>
              </span>
            )}
          </div>
          <div>
            家医：<span className='text-gray-900'>{familyDoctor}</span>
          </div>
          <div>
            团标签：<span className='text-gray-900'>{groupTag as string}</span>
          </div>
        </div>
      </div>

      <div className='space-y-2 text-xs text-gray-700'>
        <div className='font-medium text-gray-900'>预约信息</div>
        <div className='grid grid-cols-2 gap-x-8 gap-y-1'>
          <div>
            预约时间：<span className='text-gray-900'>{bookingTime as string}</span>
          </div>
          <div>
            签到时间：<span className='text-gray-900'>{signTime as string}</span>
          </div>
          <div>
            已消耗时长：
            <span className='text-gray-900'>
              {appointmentInfo?.physical_exam_complete_time && appointmentInfo?.sign_in_time
                ? `${appointmentInfo.physical_exam_complete_time} - ${appointmentInfo.sign_in_time}`
                : client.elapsed}
            </span>
          </div>
          <div className='col-span-2'>
            体检套餐名称：<span className='text-gray-900'>{client.packageName}</span>
          </div>
          <div className='col-span-2'>
            加项内容：<span className='text-gray-900'>{addonSummary as string}</span>
          </div>
        </div>
      </div>

      <div className='grid grid-cols-2 gap-4 text-xs'>
        <div className='p-3 rounded-2xl bg-green-50 border max-h-48 overflow-auto custom-scroll'>
          <div className='font-medium mb-2'>已查项目 共 {progressGroups.checked.length} 项</div>
          <div className='flex flex-wrap gap-2'>
            {(progressGroups.checked.length ? progressGroups.checked : client.checkedItems).map((i) => (
              <span key={i} className='px-2 py-0.5 rounded-full bg-white border text-[11px]'>
                {i}
              </span>
            ))}
          </div>
        </div>
        <div className='p-3 rounded-2xl bg-red-50 border max-h-48 overflow-auto custom-scroll'>
          <div className='font-medium mb-2'>弃检项目 共 {progressGroups.abandoned.length} 项</div>
          <div className='flex flex-wrap gap-2'>
            {progressGroups.abandoned.length ? (
              progressGroups.abandoned.map((i) => (
                <span key={i} className='px-2 py-0.5 rounded-full bg-white border text-[11px]'>
                  {i}
                </span>
              ))
            ) : (
              <span className='text-gray-400 text-[11px]'>暂无弃检项目</span>
            )}
          </div>
        </div>
        <div className='p-3 rounded-2xl bg-yellow-50 border max-h-48 overflow-auto custom-scroll'>
          <div className='font-medium mb-2'>未查项目 共 {progressGroups.pending.length} 项</div>
          <div className='flex flex-wrap gap-2'>
            {(progressGroups.pending.length ? progressGroups.pending : client.pendingItems).map((i) => (
              <span key={i} className='px-2 py-0.5 rounded-full bg-white border text-[11px]'>
                {i}
              </span>
            ))}
          </div>
        </div>
        <div className='p-3 rounded-2xl bg-blue-50 border max-h-48 overflow-auto custom-scroll'>
          <div className='font-medium mb-2'>延期项目 共 {progressGroups.deferred.length} 项</div>
          <div className='flex flex-wrap gap-2'>
            {progressGroups.deferred.length ? (
              progressGroups.deferred.map((i) => (
                <span key={i} className='px-2 py-0.5 rounded-full bg-white border text-[11px]'>
                  {i}
                </span>
              ))
            ) : (
              <span className='text-gray-400 text-[11px]'>暂无延期项目</span>
            )}
          </div>
        </div>
      </div>
    </div>
  );
};

const ExamDeliveryPanel = ({ client }: { client: ExamClient }) => (
  <div className='flex justify-center'>
    <div className='w-full rounded-2xl border shadow-sm px-6 py-4 text-xs text-gray-800'>
      <div className='text-lg font-semibold text-gray-900 mb-3'>报告寄送</div>
      <div className='grid grid-cols-2 gap-3 mb-3'>
        <div>
          收件人姓名
          <Input placeholder='请输入收件人姓名' className='mt-1' />
        </div>
        <div>
          联系电话
          <Input placeholder='用于快递联系' className='mt-1' />
        </div>
        <div className='col-span-2'>
          寄送地址
          <Input placeholder='请输入详细寄送地址' className='mt-1' />
        </div>
      </div>
      <div className='space-y-2'>‘
        <div>备注说明</div>
        <textarea
          className='w-full rounded-2xl border px-3 py-2 text-xs outline-none focus:ring-2 focus:ring-gray-200 min-h-[80px]'
          placeholder='如需多份报告、加急寄送等，请在此备注'
        />
      </div>
      <div className='mt-4 flex items-center justify-between text-[11px] text-gray-500'>
        <div>
          当前客户：<span className='font-medium text-gray-800'>{client.name}</span>（体检号：{client.id}）
        </div>
        <Button className='px-4 py-1.5 text-xs'>保存寄送信息</Button>
      </div>
    </div>
  </div>
);

const ExamPrintPanel = ({ client }: { client: ExamClient }) => {
  const [pdfUrl, setPdfUrl] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [pdfReady, setPdfReady] = useState(false);
  const [pdfBlobUrl, setPdfBlobUrl] = useState<string | null>(null);
  const printRef = useRef<HTMLDivElement>(null);
  const iframeRef = useRef<HTMLIFrameElement>(null);

  // 获取 PDF
  useEffect(() => {
    const physical_exam_id = Number(client.id);
    if (!physical_exam_id) {
      setError('无效的体检ID');
      setLoading(false);
      return;
    }

    setPdfReady(false);
    getTongyishuPdf({ exam_id: physical_exam_id })
      .then((res) => {
        if (res.Status === 200 && res.Data?.list_pdf_url && res.Data.list_pdf_url.length > 0) {
          // 取第一个PDF URL
          setPdfUrl(res.Data.list_pdf_url[0].pdf_url);
          setPdfReady(false);
        } else {
          setError(res.Message || '未获取到PDF文件');
        }
      })
      .catch((err) => {
        console.error('获取PDF失败', err);
        setError('获取PDF失败，请稍后重试');
      })
      .finally(() => {
        setLoading(false);
      });
  }, [client.id]);

  // 将 PDF 拉取为同源 blob，避免跨域打印限制
  useEffect(() => {
    if (!pdfUrl) return;

    let objectUrl: string | null = null;
    setPdfReady(false);
    setLoading(true);

    fetch(pdfUrl)
      .then((resp) => {
        if (!resp.ok) throw new Error('获取PDF文件失败');
        return resp.blob();
      })
      .then((blob) => {
        objectUrl = URL.createObjectURL(blob);
        setPdfBlobUrl(objectUrl);
      })
      .catch((err) => {
        console.error('PDF 拉取失败', err);
        setError('PDF 加载失败，请稍后重试');
      })
      .finally(() => {
        setLoading(false);
      });

    return () => {
      if (objectUrl) {
        URL.revokeObjectURL(objectUrl);
      }
    };
  }, [pdfUrl]);

  const handlePrint = () => {
    if (!pdfBlobUrl || !pdfReady) return;

    // 打开新窗口打印（同源 blob），避免跨域和空白页问题
    const printWindow = window.open(pdfBlobUrl, '_blank');
    if (printWindow) {
      printWindow.onload = () => {
        printWindow.focus();
        printWindow.print();
      };
    }
  };

  return (
    <div className='flex justify-center'>
      <div className='w-full max-w-[95%] bg-white rounded-2xl border shadow-sm px-6 py-4 text-xs text-gray-800'>
        <div className='flex items-center justify-between border-b pb-3 mb-3'>
          <div>
            <div className='text-sm font-semibold'>圆和医疗体检中心 · 导检单预览</div>
            <div className='text-[11px] text-gray-500 mt-1'>此为预览页面，实际打印效果以院内打印机为准。</div>
          </div>
          <div className='flex items-center gap-3'>
            <div className='text-right text-[11px] text-gray-500'>
              <div>体检号：{client.id}</div>
              <div>日期：{new Date().toLocaleDateString('zh-CN')}</div>
            </div>
            <Button
              className='px-4 py-1.5 text-xs bg-blue-600 hover:bg-blue-700 text-white disabled:opacity-50 disabled:cursor-not-allowed'
              onClick={handlePrint}
              disabled={loading || !pdfReady || !pdfUrl}
            >
              打印
            </Button>
          </div>
        </div>

        {loading ? (
          <div className='flex items-center justify-center py-12 text-gray-500'>
            <div>正在加载PDF...</div>
          </div>
        ) : error ? (
          <div className='flex flex-col items-center justify-center py-12 text-gray-500'>
            <div className='mb-2'>{error}</div>
            <Button
              className='px-4 py-1.5 text-xs'
              onClick={() => {
                setLoading(true);
                setError(null);
                const physical_exam_id = Number(client.id);
                if (physical_exam_id) {
                  getTongyishuPdf({ exam_id: physical_exam_id })
                    .then((res) => {
                      if (res.Status === 200 && res.Data?.list_pdf_url && res.Data.list_pdf_url.length > 0) {
                        setPdfUrl(res.Data.list_pdf_url[0].pdf_url);
                      } else {
                        setError(res.Message || '未获取到PDF文件');
                      }
                    })
                    .catch((err) => {
                      console.error('获取PDF失败', err);
                      setError('获取PDF失败，请稍后重试');
                    })
                    .finally(() => {
                      setLoading(false);
                    });
                }
              }}
            >
              重试
            </Button>
          </div>
        ) : pdfUrl ? (
          <div className='w-full'>
            {/* PDF预览区域 */}
            <div ref={printRef} className='print-content'>
              <div className='flex justify-center border rounded-lg p-4 bg-gray-50 overflow-auto max-h-[600px]'>
                <iframe
                  src={pdfBlobUrl || ''}
                  className='w-full h-[600px] border rounded-lg'
                  title='导检单PDF预览'
                  onLoad={() => setPdfReady(true)}
                  ref={iframeRef}
                />
              </div>
            </div>
          </div>
        ) : null}
      </div>
    </div>
  );
};


