import { useState, useEffect, useCallback } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { QRCodeSVG } from 'qrcode.react';
import styles from './Session.module.css';
import {
  finalizeTransaction,
  broadcastTransaction,
  type PreparedTransaction,
} from '../utils/transaction';

// 从 sessionStorage 获取的交易信息
interface TransactionInfo {
  preparedTx: PreparedTransaction;
  to: string;
  amount: string;
  from: string;
  walletName: string;
}

interface Participant {
  partyId: string;
  name: string;
  status: 'waiting' | 'ready' | 'processing' | 'completed' | 'failed';
}

interface SessionState {
  sessionId: string;
  walletName: string;
  messageHash: string;
  inviteCode?: string;
  threshold: { t: number; n: number };
  status: 'waiting' | 'ready' | 'processing' | 'completed' | 'failed';
  participants: Participant[];
  currentRound: number;
  totalRounds: number;
  signature?: string;
  error?: string;
}

export default function CoSignSession() {
  const { sessionId } = useParams<{ sessionId: string }>();
  const navigate = useNavigate();

  const [session, setSession] = useState<SessionState | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  // 交易广播相关状态
  const [txInfo, setTxInfo] = useState<TransactionInfo | null>(null);
  const [broadcastStep, setBroadcastStep] = useState<'idle' | 'broadcasting' | 'success' | 'error'>('idle');
  const [txHash, setTxHash] = useState<string | null>(null);
  const [broadcastError, setBroadcastError] = useState<string | null>(null);

  const fetchSessionStatus = useCallback(async () => {
    if (!sessionId) return;

    try {
      const result = await window.electronAPI.cosign.getSessionStatus(sessionId);
      if (result.success && result.session) {
        setSession({
          sessionId: result.session.sessionId || sessionId,
          walletName: result.session.walletName || '',
          messageHash: result.session.messageHash || '',
          inviteCode: result.session.inviteCode || '',
          threshold: result.session.threshold || { t: 0, n: 0 },
          status: mapStatus(result.session.status),
          participants: (result.session.participants || []).map(p => ({
            ...p,
            status: mapParticipantStatus(p.status),
          })),
          currentRound: 0,
          totalRounds: 9, // GG20 签名有 9 轮
        });
      } else {
        setError(result.error || '获取会话状态失败');
      }
    } catch (err) {
      setError('获取会话状态失败');
    } finally {
      setIsLoading(false);
    }
  }, [sessionId]);

  // 映射参与者状态
  const mapParticipantStatus = (status: string): Participant['status'] => {
    switch (status) {
      case 'waiting':
      case 'pending':
        return 'waiting';
      case 'ready':
      case 'joined':
        return 'ready';
      case 'processing':
      case 'signing':
        return 'processing';
      case 'completed':
        return 'completed';
      case 'failed':
        return 'failed';
      default:
        return 'waiting';
    }
  };

  // 映射后端状态到前端状态
  const mapStatus = (status: string): 'waiting' | 'ready' | 'processing' | 'completed' | 'failed' => {
    switch (status) {
      case 'pending':
      case 'waiting':
        return 'waiting';
      case 'all_joined':
      case 'ready':
        return 'ready';
      case 'in_progress':
      case 'signing':
        return 'processing';
      case 'completed':
        return 'completed';
      case 'failed':
      case 'expired':
        return 'failed';
      default:
        return 'waiting';
    }
  };

  // 加载交易信息
  useEffect(() => {
    if (sessionId) {
      const storedTxInfo = sessionStorage.getItem(`tx_${sessionId}`);
      if (storedTxInfo) {
        try {
          const parsed = JSON.parse(storedTxInfo);
          // 恢复 bigint 类型 (Legacy 交易使用 gasPrice)
          if (parsed.preparedTx) {
            parsed.preparedTx.gasLimit = BigInt(parsed.preparedTx.gasLimit);
            parsed.preparedTx.gasPrice = BigInt(parsed.preparedTx.gasPrice);
            parsed.preparedTx.value = BigInt(parsed.preparedTx.value);
          }
          setTxInfo(parsed);
        } catch (err) {
          console.error('Failed to parse transaction info:', err);
        }
      }
    }
  }, [sessionId]);

  useEffect(() => {
    fetchSessionStatus();

    // 订阅会话事件
    const unsubscribe = window.electronAPI.cosign.subscribeSessionEvents(
      sessionId!,
      (event: any) => {
        console.log('[CoSignSession] Received event:', event);

        if (event.type === 'participant_joined') {
          setSession(prev => prev ? {
            ...prev,
            participants: event.participant
              ? [...prev.participants, event.participant]
              : prev.participants,
          } : null);
          // 刷新状态
          fetchSessionStatus();
        } else if (event.type === 'status_changed' || event.type === 'all_joined') {
          setSession(prev => prev ? {
            ...prev,
            status: event.status ? mapStatus(event.status) : prev.status,
          } : null);
          // 刷新状态
          fetchSessionStatus();
        } else if (event.type === 'progress') {
          setSession(prev => prev ? {
            ...prev,
            status: 'processing',
            currentRound: event.round || prev.currentRound,
            totalRounds: event.totalRounds || prev.totalRounds,
          } : null);
        } else if (event.type === 'completed') {
          setSession(prev => prev ? {
            ...prev,
            status: 'completed',
            signature: event.signature,
          } : null);
        } else if (event.type === 'failed' || event.type === 'sign_start_timeout') {
          setSession(prev => prev ? {
            ...prev,
            status: 'failed',
            error: event.error,
          } : null);
        }
      }
    );

    return () => {
      unsubscribe();
    };
  }, [sessionId, fetchSessionStatus]);

  const getStatusText = (status: string) => {
    switch (status) {
      case 'waiting': return '等待参与方';
      case 'ready': return '准备就绪';
      case 'processing': return '签名进行中';
      case 'completed': return '签名完成';
      case 'failed': return '签名失败';
      default: return status;
    }
  };

  const getStatusClass = (status: string) => {
    switch (status) {
      case 'waiting': return styles.statusWaiting;
      case 'ready': return styles.statusReady;
      case 'processing': return styles.statusProcessing;
      case 'completed': return styles.statusCompleted;
      case 'failed': return styles.statusFailed;
      default: return '';
    }
  };

  const getParticipantStatusIcon = (status: string) => {
    switch (status) {
      case 'waiting': return '...';
      case 'ready': return 'OK';
      case 'processing': return '*';
      case 'completed': return 'OK';
      case 'failed': return 'X';
      default: return '-';
    }
  };

  const handleCopySignature = async () => {
    if (session?.signature) {
      try {
        await navigator.clipboard.writeText(session.signature);
      } catch (err) {
        console.error('Failed to copy:', err);
      }
    }
  };

  // 解析签名
  const parseSignature = (signatureHex: string): { r: string; s: string; v: number } | null => {
    try {
      // 签名格式: r (32 bytes) + s (32 bytes) + v (1 byte) = 65 bytes
      const sig = signatureHex.startsWith('0x') ? signatureHex.slice(2) : signatureHex;
      if (sig.length !== 130) {
        console.error('Invalid signature length:', sig.length);
        return null;
      }
      const r = sig.slice(0, 64);
      const s = sig.slice(64, 128);
      const v = parseInt(sig.slice(128, 130), 16);
      // EIP-1559 recovery id is 0 or 1
      const recoveryId = v >= 27 ? v - 27 : v;
      return { r, s, v: recoveryId };
    } catch (err) {
      console.error('Failed to parse signature:', err);
      return null;
    }
  };

  // 广播交易
  const handleBroadcastTransaction = async () => {
    if (!session?.signature || !txInfo) return;

    setBroadcastStep('broadcasting');
    setBroadcastError(null);

    try {
      // 解析签名
      const parsedSig = parseSignature(session.signature);
      if (!parsedSig) {
        throw new Error('无法解析签名');
      }

      // 构建最终交易
      const signedTx = finalizeTransaction(txInfo.preparedTx, parsedSig);

      // 广播交易
      const hash = await broadcastTransaction(signedTx);
      setTxHash(hash);
      setBroadcastStep('success');

      // 清除 sessionStorage 中的交易信息
      sessionStorage.removeItem(`tx_${sessionId}`);
    } catch (err) {
      setBroadcastError((err as Error).message);
      setBroadcastStep('error');
    }
  };

  // 获取区块浏览器交易 URL
  const getTxExplorerUrl = (hash: string): string => {
    // 从 transaction.ts 获取当前网络
    const isTestnet = typeof window !== 'undefined' &&
      window.localStorage?.getItem('kava_network') !== 'mainnet';
    const baseUrl = isTestnet
      ? 'https://testnet.kavascan.com'
      : 'https://kavascan.com';
    return `${baseUrl}/tx/${hash}`;
  };

  if (isLoading) {
    return (
      <div className={styles.container}>
        <div className={styles.loading}>
          <div className={styles.spinner}></div>
          <p>加载签名会话信息...</p>
        </div>
      </div>
    );
  }

  if (error || !session) {
    return (
      <div className={styles.container}>
        <div className={styles.error}>
          <div className={styles.errorIcon}>!</div>
          <h3>加载失败</h3>
          <p>{error || '无法获取会话信息'}</p>
          <button className={styles.primaryButton} onClick={() => navigate('/')}>
            返回首页
          </button>
        </div>
      </div>
    );
  }

  return (
    <div className={styles.container}>
      <div className={styles.card}>
        <div className={styles.header}>
          <div>
            <h1 className={styles.title}>{session.walletName || '多方签名'}</h1>
            <p className={styles.sessionId}>会话 ID: {session.sessionId?.substring(0, 16)}...</p>
          </div>
          <span className={`${styles.status} ${getStatusClass(session.status)}`}>
            {getStatusText(session.status)}
          </span>
        </div>

        <div className={styles.content}>
          {/* 邀请码 - 等待状态时显示 */}
          {session.inviteCode && session.status === 'waiting' && (
            <div className={styles.section}>
              <h3 className={styles.sectionTitle}>邀请码</h3>

              {/* QR Code */}
              <div style={{
                display: 'flex',
                justifyContent: 'center',
                marginBottom: 'var(--spacing-md)',
              }}>
                <div style={{
                  padding: 'var(--spacing-md)',
                  backgroundColor: 'white',
                  borderRadius: 'var(--radius-md)',
                  border: '1px solid var(--border-color)',
                }}>
                  <QRCodeSVG
                    value={session.inviteCode}
                    size={180}
                    level="M"
                    includeMargin={false}
                  />
                </div>
              </div>

              <div className={styles.publicKeyWrapper}>
                <code className={styles.publicKey}>{session.inviteCode}</code>
                <button
                  className={styles.copyButton}
                  onClick={async () => {
                    try {
                      await navigator.clipboard.writeText(session.inviteCode!);
                    } catch (err) {
                      console.error('Failed to copy:', err);
                    }
                  }}
                >
                  复制
                </button>
              </div>
              <p style={{ fontSize: '12px', color: 'var(--text-secondary)', marginTop: 'var(--spacing-xs)', textAlign: 'center' }}>
                扫描二维码或分享邀请码给其他参与方加入签名
              </p>
            </div>
          )}

          {/* 消息哈希 */}
          {session.messageHash && (
            <div className={styles.section}>
              <h3 className={styles.sectionTitle}>待签名消息</h3>
              <code style={{
                display: 'block',
                padding: '8px 12px',
                backgroundColor: 'var(--background-color)',
                borderRadius: 'var(--radius-md)',
                fontSize: '12px',
                wordBreak: 'break-all',
                fontFamily: 'monospace',
              }}>
                {session.messageHash}
              </code>
            </div>
          )}

          {/* 进度部分 */}
          {session.status === 'processing' && (
            <div className={styles.progress}>
              <div className={styles.progressHeader}>
                <span>签名进度</span>
                <span>{session.currentRound} / {session.totalRounds}</span>
              </div>
              <div className={styles.progressBar}>
                <div
                  className={styles.progressFill}
                  style={{ width: `${(session.currentRound / session.totalRounds) * 100}%` }}
                ></div>
              </div>
            </div>
          )}

          {/* 参与方列表 */}
          <div className={styles.section}>
            <h3 className={styles.sectionTitle}>
              参与方 ({(session.participants || []).length} / {session.threshold?.t || 0})
            </h3>
            <div className={styles.participantList}>
              {(session.participants || []).map((participant, index) => (
                <div key={participant.partyId || index} className={styles.participant}>
                  <div className={styles.participantInfo}>
                    <span className={styles.participantIndex}>#{index + 1}</span>
                    <span className={styles.participantName}>{participant.name || `参与方 ${index + 1}`}</span>
                  </div>
                  <span className={`${styles.participantStatus} ${getStatusClass(participant.status)}`}>
                    {getParticipantStatusIcon(participant.status)}
                  </span>
                </div>
              ))}
              {Array.from({ length: Math.max(0, (session.threshold?.t || 0) - (session.participants || []).length) }).map((_, index) => (
                <div key={`empty-${index}`} className={`${styles.participant} ${styles.participantEmpty}`}>
                  <div className={styles.participantInfo}>
                    <span className={styles.participantIndex}>#{(session.participants || []).length + index + 1}</span>
                    <span className={styles.participantName}>等待加入...</span>
                  </div>
                  <span className={styles.participantStatus}>...</span>
                </div>
              ))}
            </div>
          </div>

          {/* 阈值信息 */}
          {session.threshold && (
            <div className={styles.section}>
              <h3 className={styles.sectionTitle}>签名阈值</h3>
              <div className={styles.thresholdInfo}>
                <span className={styles.thresholdBadge}>
                  {session.threshold.t}-of-{session.threshold.n}
                </span>
                <span className={styles.thresholdText}>
                  需要 {session.threshold.t} 个参与方共同签名
                </span>
              </div>
            </div>
          )}

          {/* 完成状态 */}
          {session.status === 'completed' && session.signature && (
            <div className={styles.section}>
              <h3 className={styles.sectionTitle}>签名结果</h3>
              <div className={styles.publicKeyWrapper}>
                <code className={styles.publicKey}>{session.signature}</code>
                <button className={styles.copyButton} onClick={handleCopySignature}>
                  复制
                </button>
              </div>
              <p className={styles.successMessage}>
                OK 签名已成功生成
              </p>

              {/* 交易广播部分 */}
              {txInfo && (
                <div style={{ marginTop: 'var(--spacing-lg)' }}>
                  <h4 style={{
                    fontSize: '14px',
                    fontWeight: 600,
                    color: 'var(--text-primary)',
                    marginBottom: 'var(--spacing-sm)',
                  }}>
                    交易详情
                  </h4>
                  <div style={{
                    backgroundColor: 'var(--background-color)',
                    borderRadius: 'var(--radius-md)',
                    padding: 'var(--spacing-md)',
                    marginBottom: 'var(--spacing-md)',
                  }}>
                    <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '8px' }}>
                      <span style={{ color: 'var(--text-secondary)', fontSize: '13px' }}>收款地址</span>
                      <span style={{ fontFamily: 'monospace', fontSize: '13px' }}>
                        {txInfo.to.slice(0, 10)}...{txInfo.to.slice(-8)}
                      </span>
                    </div>
                    <div style={{ display: 'flex', justifyContent: 'space-between' }}>
                      <span style={{ color: 'var(--text-secondary)', fontSize: '13px' }}>转账金额</span>
                      <span style={{ fontFamily: 'monospace', fontSize: '13px', fontWeight: 600 }}>
                        {txInfo.amount} KAVA
                      </span>
                    </div>
                  </div>

                  {broadcastStep === 'idle' && (
                    <button
                      className={styles.primaryButton}
                      onClick={handleBroadcastTransaction}
                      style={{ width: '100%' }}
                    >
                      广播交易到区块链
                    </button>
                  )}

                  {broadcastStep === 'broadcasting' && (
                    <div style={{
                      textAlign: 'center',
                      padding: 'var(--spacing-md)',
                      color: 'var(--text-secondary)',
                    }}>
                      <div className={styles.spinner} style={{ margin: '0 auto var(--spacing-sm)' }}></div>
                      <p>正在广播交易...</p>
                    </div>
                  )}

                  {broadcastStep === 'success' && txHash && (
                    <div style={{
                      backgroundColor: 'rgba(40, 167, 69, 0.1)',
                      borderRadius: 'var(--radius-md)',
                      padding: 'var(--spacing-md)',
                      textAlign: 'center',
                    }}>
                      <div style={{
                        fontSize: '24px',
                        color: '#28a745',
                        marginBottom: 'var(--spacing-sm)',
                      }}>OK</div>
                      <p style={{
                        color: '#28a745',
                        fontWeight: 600,
                        marginBottom: 'var(--spacing-sm)',
                      }}>
                        交易已成功广播!
                      </p>
                      <div style={{
                        backgroundColor: 'white',
                        padding: 'var(--spacing-sm)',
                        borderRadius: 'var(--radius-sm)',
                        marginBottom: 'var(--spacing-md)',
                      }}>
                        <code style={{
                          fontSize: '12px',
                          wordBreak: 'break-all',
                          fontFamily: 'monospace',
                        }}>
                          {txHash}
                        </code>
                      </div>
                      <a
                        href={getTxExplorerUrl(txHash)}
                        target="_blank"
                        rel="noopener noreferrer"
                        style={{
                          display: 'inline-block',
                          padding: 'var(--spacing-sm) var(--spacing-md)',
                          backgroundColor: '#28a745',
                          color: 'white',
                          borderRadius: 'var(--radius-md)',
                          textDecoration: 'none',
                          fontSize: '14px',
                        }}
                      >
                        在区块浏览器查看
                      </a>
                    </div>
                  )}

                  {broadcastStep === 'error' && (
                    <div style={{
                      backgroundColor: 'rgba(220, 53, 69, 0.1)',
                      borderRadius: 'var(--radius-md)',
                      padding: 'var(--spacing-md)',
                      textAlign: 'center',
                    }}>
                      <div style={{
                        fontSize: '24px',
                        color: '#dc3545',
                        marginBottom: 'var(--spacing-sm)',
                      }}>!</div>
                      <p style={{ color: '#dc3545', marginBottom: 'var(--spacing-sm)' }}>
                        广播失败: {broadcastError}
                      </p>
                      <button
                        className={styles.secondaryButton}
                        onClick={() => setBroadcastStep('idle')}
                      >
                        重试
                      </button>
                    </div>
                  )}
                </div>
              )}
            </div>
          )}

          {/* 失败状态 */}
          {session.status === 'failed' && session.error && (
            <div className={styles.section}>
              <div className={styles.failureMessage}>
                <span className={styles.failureIcon}>!</span>
                <span>{session.error}</span>
              </div>
            </div>
          )}
        </div>

        <div className={styles.footer}>
          <button className={styles.primaryButton} onClick={() => navigate('/')}>
            返回首页
          </button>
        </div>
      </div>
    </div>
  );
}
