import { useState, useEffect, useRef, useCallback } from 'react';
import { AlertTriangle } from 'lucide-react';
import QRCodeLib from 'qrcode';
import { getWechatQrCode, pollWechatStatus } from '@/lib/api';

type BindPhase = 'loading' | 'waiting_scan' | 'scanned' | 'confirmed' | 'expired' | 'error';

interface QrData {
  qrcode: string;
  qrcode_img_url: string;
}

interface StatusData {
  status: string;
  bot_token?: string;
  ilink_bot_id?: string;
  ilink_user_id?: string;
}

const POLL_INTERVAL_MS = 2000;

export default function WeChatBind() {
  const [phase, setPhase] = useState<BindPhase>('loading');
  const [qrData, setQrData] = useState<QrData | null>(null);
  const [statusData, setStatusData] = useState<StatusData | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [qrRendered, setQrRendered] = useState(false);

  const canvasRef = useRef<HTMLCanvasElement>(null);
  const pollTimerRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const pollingQrRef = useRef<string>('');

  const stopPolling = useCallback(() => {
    if (pollTimerRef.current) { clearInterval(pollTimerRef.current); pollTimerRef.current = null; }
    pollingQrRef.current = '';
  }, []);

  const renderQrOnCanvas = useCallback(async (payload: string) => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    setQrRendered(false);
    try {
      await QRCodeLib.toCanvas(canvas, payload, {
        width: 256,
        margin: 2,
        color: { dark: '#000000', light: '#ffffff' },
      });
      setQrRendered(true);
    } catch (err) {
      console.error('Failed to render QR code:', err);
    }
  }, []);

  useEffect(() => {
    if (qrData && (phase === 'waiting_scan' || phase === 'scanned')) {
      renderQrOnCanvas(qrData.qrcode_img_url || qrData.qrcode);
    }
  }, [qrData, phase, renderQrOnCanvas]);

  const startPolling = useCallback((qrcode: string) => {
    stopPolling();
    pollingQrRef.current = qrcode;
    pollTimerRef.current = setInterval(async () => {
      if (pollingQrRef.current !== qrcode) return;
      try {
        const data = await pollWechatStatus(qrcode);
        if (pollingQrRef.current !== qrcode) return;
        setStatusData(data);
        switch (data.status) {
          case 'scaned':
            setPhase('scanned');
            break;
          case 'confirmed':
            stopPolling();
            setPhase('confirmed');
            break;
          case 'expired':
            stopPolling();
            setPhase('expired');
            break;
          default:
            setPhase((prev) => prev === 'scanned' ? 'scanned' : 'waiting_scan');
        }
      } catch (err) {
        console.warn('WeChat status poll error:', err);
      }
    }, POLL_INTERVAL_MS);
  }, [stopPolling]);

  const handleFetchQrCode = useCallback(async () => {
    stopPolling();
    setPhase('loading');
    setError(null);
    setStatusData(null);
    setQrRendered(false);
    try {
      const data = await getWechatQrCode();
      setQrData(data);
      setPhase('waiting_scan');
      startPolling(data.qrcode);
    } catch (err) {
      setPhase('error');
      setError(err instanceof Error ? err.message : String(err));
    }
  }, [stopPolling, startPolling]);

  useEffect(() => {
    handleFetchQrCode();
    return () => { stopPolling(); };
  }, []);

  return (
    <div className="h-screen w-screen flex flex-col items-center justify-center" style={{ background: '#f5f5f5' }}>
      <div className="mb-4">
        <svg width="64" height="64" viewBox="0 0 1024 1024" fill="none">
          <rect width="1024" height="1024" rx="180" fill="#07C160" />
          <circle cx="360" cy="360" r="86" fill="#fff" />
          <circle cx="664" cy="360" r="86" fill="#fff" />
          <path d="M512 640c-120 0-220-60-260-150 40-20 90-30 140-30 100 0 190-50 230-130z" fill="#fff" />
        </svg>
      </div>

      <h1 className="text-3xl font-normal mb-4" style={{ color: '#333' }}>微信</h1>

      <p className="text-base text-center mb-8 max-w-md leading-relaxed" style={{ color: '#888' }}>
        扫码接入个人微信，在聊天中直接调用 KylinBot，随时处理日常任务与问题
      </p>

      {error && (
        <div className="flex items-center gap-2 mb-6 px-4 py-2 rounded-lg" style={{ background: 'rgba(239,68,68,0.06)' }}>
          <AlertTriangle className="w-4 h-4 flex-shrink-0" style={{ color: '#ef4444' }} />
          <span className="text-sm" style={{ color: '#ef4444' }}>{error}</span>
        </div>
      )}

      {/* QR code area — always show the box for loading / waiting / scanned / expired / confirmed */}
      {(phase === 'loading' || phase === 'waiting_scan' || phase === 'scanned' || phase === 'expired' || phase === 'confirmed') && (
        <>
          <p className="text-base mb-6" style={{ color: '#333' }}>
            请使用微信扫描下方二维码
          </p>

          <div
            className={`relative inline-block rounded-xl p-6${(phase === 'loading' || phase === 'expired') ? ' cursor-pointer' : ''}`}
            style={{ background: '#fff', border: '1px solid #e5e7eb', width: 320, height: 320 }}
            onClick={(phase === 'loading' || phase === 'expired') ? handleFetchQrCode : undefined}
          >
            {/* Actual QR canvas — visible when rendered */}
            <canvas ref={canvasRef} width={256} height={256}
              className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2"
              style={{
                display: 'block',
                visibility: (qrRendered && phase !== 'loading') ? 'visible' : 'hidden',
                filter: (phase === 'expired' || phase === 'confirmed') ? 'blur(4px) opacity(0.12)' : 'none',
              }} />

            {/* Loading / Expired / Confirmed overlay — icon + text centered in the box */}
            {(phase === 'loading' || !qrRendered || phase === 'expired' || phase === 'confirmed') && (
              <div className="absolute inset-0 flex flex-col items-center justify-center gap-3">
                {phase === 'confirmed' ? null : phase === 'loading' ? (
                  <svg className="w-8 h-8 animate-spin" viewBox="0 0 50 50" fill="none">
                    <circle cx="25" cy="25" r="20" stroke="#07C160" strokeWidth="4" strokeLinecap="round"
                      strokeDasharray="90 200" />
                  </svg>
                ) : (
                  <svg className="w-8 h-8" viewBox="0 0 24 24" fill="none" stroke="#333" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                    <path d="M21 12a9 9 0 11-9-9c2.52 0 4.93 1 6.74 2.74L21 8" />
                    <path d="M21 3v5h-5" />
                  </svg>
                )}
                {phase === 'confirmed' ? (
                  <span className="text-base font-medium px-6 text-center leading-relaxed" style={{ color: '#10b981' }}>绑定成功，重启服务生效</span>
                ) : phase === 'expired' ? (
                  <span className="text-sm" style={{ color: '#333' }}>刷新二维码</span>
                ) : null}
              </div>
            )}
          </div>

          {/* Bottom status text — always reserves height (mt-6), content varies by state */}
          <div className="mt-6 h-[28px] flex items-center justify-center">
            {phase === 'scanned' ? (
              <span className="inline-flex items-center gap-1.5 px-4 py-2 rounded-full text-sm"
                style={{ background: 'rgba(59,130,246,0.08)', color: '#3b82f6', border: '1px solid rgba(59,130,246,0.2)' }}>
                已扫描，请在手机上确认...
              </span>
            ) : phase === 'expired' ? (
              <span className="text-base" style={{ color: '#ef4444', fontWeight: 500 }}>
                二维码已过期，请刷新
              </span>
            ) : phase === 'confirmed' ? (
              <span className="text-sm" style={{ color: '#aaa' }}>Bot ID: {statusData?.ilink_bot_id || '-'}</span>
            ) : null}
          </div>
        </>
      )}

      {phase === 'error' && !['waiting_scan', 'scanned', 'confirmed'].includes(phase) && (
        <div className="flex flex-col items-center gap-4">
          <AlertTriangle className="w-12 h-12" style={{ color: '#ef4444' }} />
          <p className="text-base" style={{ color: '#333' }}>出错了</p>
          <button onClick={() => { setError(null); handleFetchQrCode(); }}
            className="inline-flex items-center gap-2 px-6 py-2.5 text-base rounded-xl transition-all hover:opacity-90"
            style={{ background: '#ef4444', color: '#fff', border: 'none', cursor: 'pointer' }}>
            重试
          </button>
        </div>
      )}
    </div>
  );
}
