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

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: 160,
        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', fontFamily: "'Noto Sans CJK SC', sans-serif" }}>
      <div className="mb-2">
        <img src={`${assetBasePath}/icons/wechat.svg`} alt="WeChat" width="64" height="64" />
      </div>

      {/* 大标题 */}
      <h1 style={{
        fontFamily: "'Noto Sans CJK SC', sans-serif",
        fontSize: 24,
        fontWeight: 500,
        lineHeight: 'normal',
        textAlign: 'center',
        display: 'flex',
        alignItems: 'center',
        letterSpacing: 0,
        color: 'rgba(0, 0, 0, 0.85)',
        marginBottom: 16,
      }}>微信</h1>

      {/* 内容介绍 */}
      <p style={{
        fontFamily: "'Noto Sans CJK SC', sans-serif",
        fontSize: 14,
        fontWeight: 'normal',
        lineHeight: 'normal',
        textAlign: 'center',
        display: 'flex',
        alignItems: 'center',
        letterSpacing: 0,
        color: 'rgba(0, 0, 0, 0.6)',
        marginBottom: 16,
        maxWidth: 400,
      }}>
        扫码接入个人微信，在聊天中直接调用 KylinBot，随时处理日常任务与问题
      </p>

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

      {(phase === 'loading' || phase === 'waiting_scan' || phase === 'scanned' || phase === 'expired' || phase === 'confirmed') && (
        <>
          {/* 请扫描二维码文字 + 二维码容器 */}
          <div style={{
            display: 'flex',
            flexDirection: 'column',
            alignItems: 'center',
            padding: '8px 24px 24px 24px',
            gap: 16,
            alignSelf: 'stretch',
          }}>
            <p style={{
              fontFamily: "'Noto Sans CJK SC', sans-serif",
              fontSize: 14,
              fontWeight: 500,
              color: 'rgba(0, 0, 0, 0.85)',
              margin: 0,
            }}>
              请使用微信扫描下方二维码
            </p>

            {/* 二维码控件 */}
            <div
              className={`relative inline-block${(phase === 'loading' || phase === 'expired') ? ' cursor-pointer' : ''}`}
              style={{
                background: '#fff',
                border: '1px solid #e5e7eb',
                borderRadius: 6,
                width: 176,
                height: 176,
              }}
              onClick={(phase === 'loading' || phase === 'expired') ? handleFetchQrCode : undefined}
            >
              <canvas ref={canvasRef} width={160} height={160}
                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',
                }} />

              {(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 style={{
                      fontFamily: "'Noto Sans CJK SC', sans-serif",
                      fontSize: 10,
                      fontWeight: 500,
                      color: '#10b981',
                      textAlign: 'center',
                      padding: '0 16px',
                    }}>绑定成功，重启服务生效</span>
                  ) : phase === 'expired' ? (
                    <span style={{ fontSize: 14, color: 'rgba(0,0,0,0.6)' }}>刷新二维码</span>
                  ) : null}
                </div>
              )}
            </div>
          </div>

          {/* 底部状态文字 */}
          <div className="mt-4 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 style={{ fontSize: 14, color: '#ef4444', fontWeight: 500 }}>
                二维码已过期，请刷新
              </span>
            ) : phase === 'confirmed' ? (
              <span style={{ fontSize: 14, color: 'rgba(0,0,0,0.45)' }}>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 style={{ fontSize: 14, color: 'rgba(0,0,0,0.85)' }}>出错了</p>
          <button onClick={() => { setError(null); handleFetchQrCode(); }}
            className="inline-flex items-center gap-2 px-6 py-2.5 rounded-xl transition-all hover:opacity-90"
            style={{ background: '#ef4444', color: '#fff', border: 'none', cursor: 'pointer', borderRadius: 6, fontSize: 14 }}>
            重试
          </button>
        </div>
      )}
    </div>
  );
}
