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';
import { useLocale } from '@/lib/i18n';

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({ onBindSuccess }: { onBindSuccess?: () => void }) {
  const { t } = useLocale();
  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');
            onBindSuccess?.();
            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="flex flex-col items-center" style={{ fontFamily: "'Noto Sans CJK SC', sans-serif", paddingTop: 48 }}>
      <div style={{ marginBottom: 8 }}>
        <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',
        letterSpacing: 0,
        color: '#000000',
        marginBottom: 2,
      }}>{t('channel.wechat')}</h1>

      <p style={{
        fontFamily: "'Noto Sans CJK SC', sans-serif",
        fontSize: 14,
        fontWeight: 400,
        lineHeight: 'normal',
        textAlign: 'center',
        letterSpacing: 0,
        color: 'rgba(0, 0, 0, 0.6)',
        marginBottom: 16,
        maxWidth: 400,
      }}>
        {t('channel.wechat.desc')}
      </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') && (
        <>
          <p style={{
            fontFamily: "'Noto Sans CJK SC', sans-serif",
            fontSize: 14,
            fontWeight: 700,
            color: 'rgba(0, 0, 0, 0.85)',
            marginBottom: 16,
          }}>
            {t('channel.scan_tip')}
          </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-4 h-4" 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',
                  }}>{t('channel.bind_success')}</span>
                ) : phase === 'expired' ? (
                  <span style={{ fontSize: 14, color: 'rgba(0,0,0,0.6)', marginTop: -8 }}>{t('channel.refresh_qr')}</span>
                ) : null}
              </div>
            )}
          </div>

          <div className="mt-2 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)' }}>
                {t('channel.scanned_confirm')}
              </span>
            ) : phase === 'expired' ? (
              <span style={{ fontSize: 14, color: '#F53F3F', fontWeight: 400 }}>
                {t('channel.qr_expired')}
              </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)' }}>{t('channel.bind_error')}</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 }}>
            {t('channel.retry')}
          </button>
        </div>
      )}
    </div>
  );
}
