import { useState, useEffect, useRef, useCallback } from 'react';
import { AlertTriangle, Eye, EyeOff } from 'lucide-react';
import QRCodeLib from 'qrcode';
import { beginFeishuRegistration, pollFeishuRegistration, saveFeishuWebSocketConfig } from '@/lib/api';
import { assetBasePath } from '@/lib/basePath';

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

type ReceiveMode = 'qrcode' | 'websocket';

const POLL_INTERVAL_MS = 2000;

export default function FeishuBind() {
  const [mode, setMode] = useState<ReceiveMode>('qrcode');
  const [phase, setPhase] = useState<BindPhase>('loading');
  const [qrUrl, setQrUrl] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [qrRendered, setQrRendered] = useState(false);

  const [appId, setAppId] = useState('');
  const [appSecret, setAppSecret] = useState('');
  const [showSecret, setShowSecret] = useState(false);
  const [submitting, setSubmitting] = useState(false);

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

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

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

  useEffect(() => {
    if (qrUrl && (phase === 'waiting_scan' || phase === 'scanned')) {
      renderQrOnCanvas(qrUrl);
    }
  }, [qrUrl, phase, renderQrOnCanvas]);

  const startPolling = useCallback((code: string) => {
    stopPolling();
    pollingDeviceCodeRef.current = code;
    pollTimerRef.current = setInterval(async () => {
      if (pollingDeviceCodeRef.current !== code) return;
      try {
        const data = await pollFeishuRegistration(code);
        if (pollingDeviceCodeRef.current !== code) return;

        if (data.client_id && data.client_secret) {
          stopPolling();
          setPhase('confirmed');
          return;
        }

        switch (data.error) {
          case 'authorization_pending':
          case undefined:
            break;
          case 'slow_down':
            console.log('Server requested slower polling');
            break;
          case 'access_denied':
            stopPolling();
            setError(data.error_description || '用户拒绝了授权');
            setPhase('error');
            break;
          case 'expired_token':
            stopPolling();
            setPhase('expired');
            break;
          default:
            if (data.error) {
              console.warn('Feishu poll error:', data.error, data.error_description);
            }
        }
      } catch (err) {
        console.warn('Feishu status poll error:', err);
      }
    }, POLL_INTERVAL_MS);
  }, [stopPolling]);

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

  useEffect(() => {
    if (mode === 'qrcode') {
      handleFetchQrCode();
    }
    return () => {
      stopPolling();
    };
  }, [mode]);

  const handleModeChange = (newMode: ReceiveMode) => {
    setMode(newMode);
    if (newMode === 'websocket') {
      stopPolling();
      setPhase('loading');
      setError(null);
      setAppId('');
      setAppSecret('');
      setTimeout(() => setPhase('ws_success'), 100);
    } else {
      handleFetchQrCode();
    }
  };

  const handleWsConnect = async () => {
    if (!appId.trim() || !appSecret.trim()) {
      setError('请填写 App ID 和 App Secret');
      return;
    }

    setSubmitting(true);
    setError(null);
    try {
      await saveFeishuWebSocketConfig(appId.trim(), appSecret.trim());
      setPhase('confirmed');
    } catch (err) {
      setPhase('error');
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setSubmitting(false);
    }
  };

  const handleCancel = () => {
    setAppId('');
    setAppSecret('');
    setShowSecret(false);
    setError(null);
  };

  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/feishu.svg`} alt="Feishu" 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>

      {/* Receive mode selector */}
      {(phase !== 'error' || mode === 'websocket') && (
        <div className="mb-4 flex items-center gap-6">
          <label className="flex items-center gap-2 cursor-pointer">
            <input
              type="radio"
              name="receiveMode"
              value="qrcode"
              checked={mode === 'qrcode'}
              onChange={() => handleModeChange('qrcode')}
              className="w-4 h-4 accent-[#3370FF]"
            />
            <span style={{ fontSize: 14, color: mode === 'qrcode' ? 'rgba(0,0,0,0.85)' : 'rgba(0,0,0,0.45)' }}>扫码接入</span>
          </label>
          <label className="flex items-center gap-2 cursor-pointer">
            <input
              type="radio"
              name="receiveMode"
              value="websocket"
              checked={mode === 'websocket'}
              onChange={() => handleModeChange('websocket')}
              className="w-4 h-4 accent-[#3370FF]"
            />
            <span style={{ fontSize: 14, color: mode === 'websocket' ? 'rgba(0,0,0,0.85)' : 'rgba(0,0,0,0.45)' }}>WebSocket 长连接</span>
          </label>
        </div>
      )}

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

      {/* ====== WebSocket Mode Form ====== */}
      {mode === 'websocket' && (
        <>
          {phase === 'confirmed' ? (
            <div className="flex flex-col items-center gap-4 mt-4">
              <svg className="w-12 h-12" viewBox="0 0 24 24" fill="none" stroke="#10b981" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                <path d="M22 11.08V12a10 10 0 11-5.93-9.14" />
                <polyline points="22 4 12 14.01 9 11.01" />
              </svg>
              <span style={{
                fontFamily: "'Noto Sans CJK SC', sans-serif",
                fontSize: 10,
                fontWeight: 500,
                color: '#10b981',
                textAlign: 'center',
              }}>
                绑定成功，重启服务生效
              </span>
            </div>
          ) : (
            <div className="w-full max-w-md flex flex-col gap-5 pt-2">
              <div className="flex flex-col gap-1.5">
                <label style={{
                  fontFamily: "'Noto Sans CJK SC', sans-serif",
                  fontSize: 14,
                  fontWeight: 500,
                  color: 'rgba(0, 0, 0, 0.85)',
                }}>
                  App ID <span style={{ color: '#ef4444' }}>*</span>
                </label>
                <input
                  type="text"
                  value={appId}
                  onChange={(e) => setAppId(e.target.value)}
                  placeholder="请输入 App ID"
                  className="w-full px-4 py-3 text-sm outline-none transition-all focus:ring-2 focus:ring-[#3370FF]/30"
                  style={{
                    fontFamily: "'Noto Sans CJK SC', sans-serif",
                    fontSize: 14,
                    background: '#fff',
                    border: '1px solid #e5e7eb',
                    borderRadius: 6,
                    color: '#333',
                  }}
                />
              </div>

              <div className="flex flex-col gap-1.5">
                <label style={{
                  fontFamily: "'Noto Sans CJK SC', sans-serif",
                  fontSize: 14,
                  fontWeight: 500,
                  color: 'rgba(0, 0, 0, 0.85)',
                }}>
                  App Secret <span style={{ color: '#ef4444' }}>*</span>
                </label>
                <div className="relative">
                  <input
                    type={showSecret ? 'text' : 'password'}
                    value={appSecret}
                    onChange={(e) => setAppSecret(e.target.value)}
                    placeholder="请输入 App Secret"
                    className="w-full px-4 py-3 pr-10 text-sm outline-none transition-all focus:ring-2 focus:ring-[#3370FF]/30"
                    style={{
                      fontFamily: "'Noto Sans CJK SC', sans-serif",
                      fontSize: 14,
                      background: '#fff',
                      border: '1px solid #e5e7eb',
                      borderRadius: 6,
                      color: '#333',
                    }}
                  />
                  <button
                    type="button"
                    onClick={() => setShowSecret(!showSecret)}
                    className="absolute right-3 top-1/2 -translate-y-1/2 p-1 rounded hover:bg-gray-100 transition-colors"
                  >
                    {showSecret ? (
                      <EyeOff className="w-4 h-4" style={{ color: '#999' }} />
                    ) : (
                      <Eye className="w-4 h-4" style={{ color: '#999' }} />
                    )}
                  </button>
                </div>
              </div>

              <div className="flex items-center justify-end gap-3 pt-2">
                <button
                  onClick={handleCancel}
                  disabled={submitting}
                  style={{
                    fontFamily: "'Noto Sans CJK SC', sans-serif",
                    fontSize: 14,
                    padding: '10px 24px',
                    borderRadius: 6,
                    background: '#fff',
                    color: 'rgba(0, 0, 0, 0.6)',
                    border: '1px solid #e5e7eb',
                    cursor: submitting ? 'not-allowed' : 'pointer',
                  }}
                >
                  取消
                </button>
                <button
                  onClick={handleWsConnect}
                  disabled={submitting || !appId.trim() || !appSecret.trim()}
                  className="inline-flex items-center gap-2 transition-all hover:opacity-90 disabled:opacity-50"
                  style={{
                    fontFamily: "'Noto Sans CJK SC', sans-serif",
                    fontSize: 14,
                    fontWeight: 500,
                    padding: '10px 24px',
                    borderRadius: 6,
                    background: submitting ? '#93c5fd' : '#3370FF',
                    color: '#fff',
                    border: 'none',
                    cursor: (!submitting && appId.trim() && appSecret.trim()) ? 'pointer' : 'not-allowed',
                  }}
                >
                  {submitting && (
                    <svg className="w-4 h-4 animate-spin" viewBox="0 0 50 50" fill="none">
                      <circle cx="25" cy="25" r="20" stroke="#fff" strokeWidth="4" strokeLinecap="round" strokeDasharray="90 200" />
                    </svg>
                  )}
                  连接
                </button>
              </div>
            </div>
          )}
        </>
      )}

      {/* ====== QR Code Mode ====== */}
      {mode === 'qrcode' && (
        <>
          {(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',
            }}>
              <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="#3370FF" 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"
                style={{ background: 'rgba(59,130,246,0.08)', color: '#3b82f6', border: '1px solid rgba(59,130,246,0.2)', fontSize: 14 }}>
                已扫描，请在手机上确认...
              </span>
            ) : phase === 'expired' ? (
              <span style={{ fontSize: 14, color: '#ef4444', fontWeight: 500 }}>
                二维码已过期，请刷新
              </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 transition-all hover:opacity-90"
            style={{
              fontFamily: "'Noto Sans CJK SC', sans-serif",
              fontSize: 14,
              padding: '10px 24px',
              borderRadius: 6,
              background: '#ef4444',
              color: '#fff',
              border: 'none',
              cursor: 'pointer',
            }}>
            重试
          </button>
        </div>
      )}
    </div>
  );
}
