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

import type { OutputTongyishuFileInfo } from '../../api';
import { getTongyishuPdf, signInMedicalExamCenter, submitTongyishuSign } from '../../api';
import { setExamActionRecord } from '../../utils/examActions';
import type { SignaturePadHandle } from '../ui';
import { Button, SignaturePad } from '../ui';

interface ExamSignPanelProps {
  examId?: number;
  onBusyChange?: (busy: boolean) => void;
}

export const ExamSignPanel = ({ examId, onBusyChange }: ExamSignPanelProps) => {
  const [idCardFile, setIdCardFile] = useState<File | null>(null);
  const [previewImage, setPreviewImage] = useState<string | null>(null);
  const [showImagePreview, setShowImagePreview] = useState(false);
  const [signLoading, setSignLoading] = useState(false);
  const [message, setMessage] = useState<string | null>(null);
  const fileInputRef = useRef<HTMLInputElement | null>(null);
  const [consentList, setConsentList] = useState<OutputTongyishuFileInfo[]>([]);
  const [consentLoading, setConsentLoading] = useState(false);
  const [consentMessage, setConsentMessage] = useState<string | null>(null);
  const [previewPdf, setPreviewPdf] = useState<OutputTongyishuFileInfo | null>(null);
  const [showSignature, setShowSignature] = useState(false);
  const signaturePadRef = useRef<SignaturePadHandle | null>(null);
  const [submitLoading, setSubmitLoading] = useState(false);
  const [submitMessage, setSubmitMessage] = useState<string | null>(null);
  const [signedCombinationCodes, setSignedCombinationCodes] = useState<number[]>([]);
  const busy = signLoading || submitLoading || consentLoading;

  useEffect(() => {
    onBusyChange?.(busy);
    return () => onBusyChange?.(false);
  }, [busy, onBusyChange]);

  const SIGN_STORAGE_KEY = 'yh_signed_consents';

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

  useEffect(() => {
    if (typeof window === 'undefined') return;
    const raw = localStorage.getItem(SIGN_STORAGE_KEY);
    if (raw) {
      try {
        const parsed = JSON.parse(raw);
        if (Array.isArray(parsed)) {
          setSignedCombinationCodes(parsed.filter((x) => typeof x === 'number'));
        }
      } catch (err) {
        console.warn('签名记录解析失败', err);
      }
    }
  }, []);

  const convertToJpg = async (file: File): Promise<File> => {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = (event) => {
        const img = new Image();
        img.onload = () => {
          const canvas = document.createElement('canvas');
          canvas.width = img.width;
          canvas.height = img.height;
          const ctx = canvas.getContext('2d');
          if (!ctx) {
            reject(new Error('无法创建画布上下文'));
            return;
          }
          ctx.drawImage(img, 0, 0);
          canvas.toBlob(
            (blob) => {
              if (!blob) {
                reject(new Error('图片转换失败'));
                return;
              }
              const jpgFile = new File([blob], 'id_card.jpg', { type: 'image/jpeg' });
              resolve(jpgFile);
            },
            'image/jpeg',
            0.92
          );
        };
        img.onerror = () => reject(new Error('图片加载失败'));
        img.src = event.target?.result as string;
      };
      reader.onerror = () => reject(new Error('文件读取失败'));
      reader.readAsDataURL(file);
    });
  };

  const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    setMessage(null);

    try {
      const jpgFile = await convertToJpg(file);
      setIdCardFile(jpgFile);

      const reader = new FileReader();
      reader.onload = (event) => {
        setPreviewImage(event.target?.result as string);
      };
      reader.readAsDataURL(jpgFile);
    } catch (err) {
      console.error('图片转换失败', err);
      setMessage('图片处理失败，请重试');
    }

    e.target.value = '';
  };

  const handleSign = async () => {
    if (!idCardFile) {
      setMessage('请先上传身份证照片');
      return;
    }
    setSignLoading(true);
    setMessage(null);
    try {
      const res = await signInMedicalExamCenter({ id_no_pic: idCardFile });
      const ok = res.Status === 200 && res.Data?.is_success === 0;
      if (ok) {
        setMessage('签到成功');
        // 记录身份证拍照与签到操作
        if (examId) {
          setExamActionRecord(examId, 'idCardSignIn', true);
        }
      } else {
        setMessage(res.Message || '签到失败');
      }
    } catch (err) {
      console.error(err);
      setMessage('签到请求失败，请稍后重试');
    } finally {
      setSignLoading(false);
    }
  };

  const handleSubmitSign = async () => {
    if (!examId || !previewPdf?.combination_code) {
      setSubmitMessage('缺少必要信息，无法提交签名');
      return;
    }

    const dataUrl = signaturePadRef.current?.toDataURL('image/png');
    if (!dataUrl) {
      setSubmitMessage('请先完成签名');
      return;
    }

    setSubmitLoading(true);
    setSubmitMessage(null);
    try {
      const blob = await fetch(dataUrl).then((r) => r.blob());

      const res = await submitTongyishuSign({
        exam_id: examId,
        combination_code: previewPdf.combination_code,
        sign_file: blob,
      });

      if (res.Status === 200) {
        setSubmitMessage('签名提交成功');
        // 记录体检知情同意书的签字操作
        if (examId) {
          setExamActionRecord(examId, 'consentSign', true);
        }
        setSignedCombinationCodes((prev) => {
          const code = Number(previewPdf.combination_code);
          if (!Number.isFinite(code)) return prev || [];
          const next = Array.from(new Set([...(prev || []), code]));
          if (typeof window !== 'undefined') {
            localStorage.setItem(SIGN_STORAGE_KEY, JSON.stringify(next));
          }
          return next;
        });
        setTimeout(() => {
          setShowSignature(false);
          setPreviewPdf(null);
          setSubmitMessage(null);
          signaturePadRef.current?.clear();
        }, 2000);
      } else {
        setSubmitMessage(res.Message || '签名提交失败');
      }
    } catch (err) {
      console.error('提交签名失败', err);
      setSubmitMessage('签名提交失败，请稍后重试');
    } finally {
      setSubmitLoading(false);
    }
  };

  useEffect(() => {
    if (!examId) {
      setConsentList([]);
      setConsentMessage('缺少体检ID，无法获取知情同意书');
      return;
    }
    setConsentLoading(true);
    setConsentMessage(null);
    getTongyishuPdf({ exam_id: examId })
      .then((res) => {
        const list = res.Data?.list_pdf_url || [];
        setConsentList(list);
        if (!list.length) {
          setConsentMessage(res.Data?.message || '暂无知情同意书');
        }
      })
      .catch((err) => {
        console.error('获取知情同意书失败', err);
        setConsentMessage('知情同意书加载失败，请稍后重试');
      })
      .finally(() => setConsentLoading(false));
  }, [examId]);

  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={busy}>
            {idCardFile ? '重新拍照' : '拍照'}
          </Button>
          <input
            ref={fileInputRef}
            type='file'
            accept='image/*'
            capture='environment'
            className='hidden'
            onChange={handleFileChange}
          />
          {previewImage && (
            <div
              className='w-16 h-16 rounded-lg border-2 border-gray-300 overflow-hidden cursor-pointer hover:border-blue-500 transition-colors'
              onClick={() => setShowImagePreview(true)}
            >
              <img src={previewImage} alt='身份证预览' className='w-full h-full object-cover' />
            </div>
          )}
          <Button className='py-1.5 px-4 flex-1' onClick={handleSign} disabled={busy || !idCardFile}>
            {signLoading ? '签到中...' : '签到'}
          </Button>
        </div>
        {message && (
          <div className={`text-xs ${message.includes('成功') ? 'text-green-600' : 'text-amber-600'}`}>{message}</div>
        )}
      </div>
      {showImagePreview && previewImage && (
        <div className='fixed inset-0 z-[80] bg-black/90 flex items-center justify-center p-6' onClick={() => setShowImagePreview(false)}>
          <div className='relative max-w-full max-h-full'>
            <img src={previewImage} alt='身份证预览' className='max-w-full max-h-[90vh] object-contain' />
            <Button className='absolute top-4 right-4 bg-white/90 hover:bg-white' onClick={() => setShowImagePreview(false)}>
              关闭
            </Button>
          </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>
        <div className='flex flex-col gap-2'>
          {consentLoading && <div className='text-xs text-gray-500'>加载中...</div>}
          {!consentLoading && consentMessage && <div className='text-xs text-amber-600'>{consentMessage}</div>}
          {!consentLoading && consentList.length > 0 && (
            <div className='space-y-2'>
              {consentList.map((item) => (
                <div
                  key={item.pdf_url || item.pdf_name}
                  className='flex items-center justify-between gap-3 p-3 rounded-xl border bg-white shadow-sm'
                >
                  <div className='text-sm text-gray-800 truncate flex items-center gap-2 relative pr-20'>
                    <span className='truncate'>{item.pdf_name}</span>
                    {item.combination_code !== undefined && signedCombinationCodes.includes(Number(item.combination_code)) && (
                      <img
                        src='/sign.png'
                        alt='已签名'
                        className='w-16 h-16 absolute right-2 top-1/2 -translate-y-1/2 pointer-events-none select-none'
                        loading='lazy'
                      />
                    )}
                  </div>
                  <Button className='py-1.5 px-3' onClick={() => !busy && setPreviewPdf(item)} disabled={busy}>
                    查看
                  </Button>
                </div>
              ))}
            </div>
          )}
        </div>
      </div>
      {previewPdf && (
        <div className='fixed inset-0 z-[60] bg-black/75 flex flex-col'>
          <div className='flex items-center justify-between p-4 text-white bg-gray-900/80'>
            <div className='text-sm font-medium truncate pr-3'>{previewPdf.pdf_name}</div>
            <div className='flex items-center gap-2'>
              <Button className='py-1 px-3' onClick={() => !busy && setShowSignature(true)} disabled={busy}>
                签到
              </Button>
              <Button className='py-1 px-3' onClick={() => !busy && setPreviewPdf(null)} disabled={busy}>
                关闭
              </Button>
            </div>
          </div>
          <div className='flex-1 bg-gray-100'>
            <iframe src={previewPdf.pdf_url} title={previewPdf.pdf_name} className='w-full h-full' />
          </div>
        </div>
      )}
      {showSignature && (
        <div className='fixed inset-0 z-[70] bg-black/80 flex items-center justify-center px-6'>
          <div className='bg-white rounded-2xl w-full max-w-3xl shadow-2xl p-4 flex flex-col gap-4'>
            <div className='flex items-center justify之间'>
              <div className='text-base font-semibold text-gray-900'>签署知情同意书</div>
              <div className='flex items-center gap-2'>
                <Button className='py-1 px-3' onClick={() => setShowSignature(false)} disabled={busy}>
                  关闭
                </Button>
              </div>
            </div>
            <div className='ui7-signature-wrapper border rounded-xl overflow-hidden bg-gray-50'>
              <SignaturePad
                ref={signaturePadRef}
                className='ui7-signature-canvas w-full h-72 bg-white touch-none'
              />
              <div className='flex items-center justify-between px-3 py-2 bg-gray-50 border-t'>
                <div className='text-xs text-gray-500'>请在上方区域签名完成签到</div>
                <Button className='ui7-clear-button py-1 px-3' onClick={() => signaturePadRef.current?.clear()} disabled={submitLoading}>
                  清除
                </Button>
              </div>
            </div>
            {submitMessage && (
              <div className={`text-sm text-center ${submitMessage.includes('成功') ? 'text-green-600' : 'text-amber-600'}`}>{submitMessage}</div>
            )}
            <div className='flex items-center justify-end gap-3'>
              <Button
                className='py-2 px-6'
                onClick={() => {
                  setShowSignature(false);
                  setSubmitMessage(null);
                  signaturePadRef.current?.clear();
                }}
                disabled={submitLoading}
              >
                取消
              </Button>
              <Button
                className='py-2 px-6 bg-blue-600 text-white hover:bg-blue-700'
                onClick={handleSubmitSign}
                disabled={submitLoading}
              >
                {submitLoading ? '提交中...' : '提交签名'}
              </Button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};


