'use client';

import { useState, useEffect, useRef, useCallback } from 'react';
import styles from './co-managed-wallet.module.scss';
import { cn } from '@/utils/helpers';
import ThresholdConfig from './ThresholdConfig';
import InviteQRCode from './InviteQRCode';
import ParticipantList from './ParticipantList';
import SessionProgress from './SessionProgress';
import WalletResult from './WalletResult';
import {
  coManagedWalletService,
  CoManagedWalletSession,
} from '@/services/coManagedWalletService';
import { useTSSClient } from '@/hooks/useTSSClient';
import { shareStorage } from '@/lib/storage';

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

interface SessionState {
  sessionId: string;
  inviteCode: string;
  inviteUrl: string;
  status: 'waiting' | 'ready' | 'processing' | 'completed' | 'failed';
  participants: Participant[];
  currentRound: number;
  totalRounds: number;
  publicKey?: string;
  error?: string;
  createdAt?: string;
  partyId?: string; // 当前参与方 ID
  partyIndex?: number; // 当前参与方索引
}

interface CreateWalletModalProps {
  isOpen: boolean;
  onClose: () => void;
  onSuccess?: () => void;
}

type Step = 'config' | 'invite' | 'progress' | 'result';

// 轮询间隔 (毫秒)
const POLL_INTERVAL = 2000;

/**
 * 将 API 会话转换为本地状态
 */
function mapApiSessionToState(apiSession: CoManagedWalletSession): SessionState {
  return {
    sessionId: apiSession.sessionId,
    inviteCode: apiSession.inviteCode,
    inviteUrl: apiSession.inviteUrl,
    status: apiSession.status as SessionState['status'],
    participants: apiSession.participants.map((p) => ({
      partyId: p.partyId,
      name: p.name,
      status: p.status as Participant['status'],
      joinedAt: p.joinedAt,
    })),
    currentRound: apiSession.currentRound,
    totalRounds: apiSession.totalRounds,
    publicKey: apiSession.publicKey,
    error: apiSession.error,
    createdAt: apiSession.createdAt,
  };
}

/**
 * 创建共管钱包向导对话框
 */
export default function CreateWalletModal({
  isOpen,
  onClose,
  onSuccess,
}: CreateWalletModalProps) {
  const [step, setStep] = useState<Step>('config');
  const [walletName, setWalletName] = useState('');
  const [thresholdT, setThresholdT] = useState(2);
  const [thresholdN, setThresholdN] = useState(3);
  const [initiatorName, setInitiatorName] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [session, setSession] = useState<SessionState | null>(null);
  const [sharePassword, setSharePassword] = useState('');
  const [showPasswordDialog, setShowPasswordDialog] = useState(false);
  const [keygenProgress, setKeygenProgress] = useState({ current: 0, total: 4 });

  // TSS 客户端
  const {
    isInitialized: isTSSReady,
    isInitializing: isTSSInitializing,
    error: tssError,
    keygen,
    registerParty,
    disconnect: disconnectTSS,
  } = useTSSClient({ autoInit: true });

  // 轮询定时器引用
  const pollTimerRef = useRef<NodeJS.Timeout | null>(null);

  // 清除轮询定时器
  const stopPolling = useCallback(() => {
    if (pollTimerRef.current) {
      clearInterval(pollTimerRef.current);
      pollTimerRef.current = null;
    }
  }, []);

  // 轮询会话状态
  const pollSessionStatus = useCallback(async (sessionId: string) => {
    try {
      const apiSession = await coManagedWalletService.getSession(sessionId);
      const updatedSession = mapApiSessionToState(apiSession);
      setSession(updatedSession);

      // 检查是否完成或失败
      if (updatedSession.status === 'completed') {
        stopPolling();
        setStep('result');
        onSuccess?.();
      } else if (updatedSession.status === 'failed') {
        stopPolling();
        setError(updatedSession.error || '密钥生成失败');
      }
    } catch (err) {
      console.error('轮询会话状态失败:', err);
    }
  }, [stopPolling, onSuccess]);

  // 开始轮询
  const startPolling = useCallback((sessionId: string) => {
    stopPolling();
    pollTimerRef.current = setInterval(() => {
      pollSessionStatus(sessionId);
    }, POLL_INTERVAL);
  }, [stopPolling, pollSessionStatus]);

  // 重置状态
  useEffect(() => {
    if (!isOpen) {
      stopPolling();
      disconnectTSS();
      setStep('config');
      setWalletName('');
      setThresholdT(2);
      setThresholdN(3);
      setInitiatorName('');
      setIsLoading(false);
      setError(null);
      setSession(null);
      setSharePassword('');
      setShowPasswordDialog(false);
      setKeygenProgress({ current: 0, total: 4 });
    }
  }, [isOpen, stopPolling, disconnectTSS]);

  // 组件卸载时清除定时器
  useEffect(() => {
    return () => {
      stopPolling();
    };
  }, [stopPolling]);

  // 创建会话
  const handleCreateSession = async () => {
    if (!walletName.trim()) {
      setError('请输入钱包名称');
      return;
    }
    if (!initiatorName.trim()) {
      setError('请输入您的名称');
      return;
    }
    if (thresholdT > thresholdN) {
      setError('签名阈值不能大于参与方总数');
      return;
    }

    // 检查 TSS 客户端是否就绪
    if (!isTSSReady) {
      if (isTSSInitializing) {
        setError('TSS 客户端正在初始化，请稍候...');
      } else {
        setError('TSS 客户端初始化失败: ' + (tssError || '未知错误'));
      }
      return;
    }

    setIsLoading(true);
    setError(null);

    try {
      // 生成唯一的 partyId
      const partyId = `admin-web-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;

      // 先注册为参与方
      await registerParty(partyId, 'initiator');

      const result = await coManagedWalletService.createSession({
        walletName: walletName.trim(),
        thresholdT,
        thresholdN,
        initiatorName: initiatorName.trim(),
        partyId, // 传递 partyId 到后端
      });

      if (result.success && result.session) {
        const sessionState = mapApiSessionToState(result.session);
        // 添加自己的 partyId
        sessionState.partyId = partyId;
        sessionState.partyIndex = 0; // 发起者通常是索引 0
        setSession(sessionState);
        setStep('invite');
        // 开始轮询会话状态
        startPolling(sessionState.sessionId);
      } else {
        setError('创建会话失败');
      }
    } catch (err: unknown) {
      const errorMessage =
        err instanceof Error ? err.message : '创建会话失败，请重试';
      setError(errorMessage);
    } finally {
      setIsLoading(false);
    }
  };

  // 开始密钥生成 - 显示密码对话框
  const handleStartKeygen = async () => {
    if (!session) return;
    // 显示密码输入对话框
    setShowPasswordDialog(true);
  };

  // 确认密码后开始密钥生成
  const handleConfirmKeygen = async () => {
    if (!session || !sharePassword) {
      setError('请输入密码以保护您的密钥份额');
      return;
    }

    if (sharePassword.length < 8) {
      setError('密码长度至少为 8 位');
      return;
    }

    setShowPasswordDialog(false);
    setIsLoading(true);
    setError(null);
    setStep('progress');

    try {
      // 通知后端开始 keygen
      const apiSession = await coManagedWalletService.startKeygen(session.sessionId);
      const updatedSession = mapApiSessionToState(apiSession);
      updatedSession.partyId = session.partyId;
      updatedSession.partyIndex = session.partyIndex;
      setSession(updatedSession);

      // 构建参与方列表
      const participants = session.participants.map((p, idx) => ({
        partyId: p.partyId,
        partyIndex: idx,
      }));

      // 使用 TSS 客户端参与 keygen
      const result = await keygen(
        {
          sessionId: session.sessionId,
          partyId: session.partyId!,
          partyIndex: session.partyIndex ?? 0,
          threshold: thresholdT,
          totalParties: thresholdN,
          participants,
        },
        (current, total) => {
          setKeygenProgress({ current, total });
          setSession((prev) =>
            prev
              ? {
                  ...prev,
                  currentRound: current,
                  totalRounds: total,
                  status: 'processing',
                }
              : null
          );
        }
      );

      // Keygen 成功，保存 share 到本地存储
      await shareStorage.saveShare(
        {
          id: `${session.sessionId}-${session.partyId}`,
          sessionId: session.sessionId,
          walletName: walletName,
          partyId: session.partyId!,
          partyIndex: session.partyIndex ?? 0,
          threshold: { t: thresholdT, n: thresholdN },
          publicKey: result.publicKey,
          rawShare: result.share,
          createdAt: new Date().toISOString(),
          metadata: {
            participants: session.participants.map((p) => ({
              partyId: p.partyId,
              name: p.name,
            })),
          },
        },
        sharePassword
      );

      // 更新会话状态
      setSession((prev) =>
        prev
          ? {
              ...prev,
              status: 'completed',
              publicKey: result.publicKey,
              currentRound: keygenProgress.total,
            }
          : null
      );

      // 通知后端完成
      await coManagedWalletService.updateSessionStatus(session.sessionId, 'completed', {
        publicKey: result.publicKey,
      });

      stopPolling();
      setStep('result');
      onSuccess?.();
    } catch (err: unknown) {
      const errorMessage =
        err instanceof Error ? err.message : '密钥生成失败';
      setError(errorMessage);
      setSession((prev) =>
        prev ? { ...prev, status: 'failed', error: errorMessage } : null
      );
    } finally {
      setIsLoading(false);
    }
  };

  // 取消会话
  const handleCancel = async () => {
    if (session) {
      stopPolling();
      try {
        await coManagedWalletService.cancelSession(session.sessionId);
      } catch (err) {
        console.error('取消会话失败:', err);
      }
    }
    onClose();
  };

  // 渲染步骤指示器
  const renderStepIndicator = () => {
    const steps = [
      { key: 'config', label: '配置' },
      { key: 'invite', label: '邀请' },
      { key: 'progress', label: '生成' },
      { key: 'result', label: '完成' },
    ];

    const currentIndex = steps.findIndex((s) => s.key === step);

    return (
      <div className={styles.createWalletModal__steps}>
        {steps.map((s, index) => (
          <div
            key={s.key}
            className={cn(
              styles.createWalletModal__step,
              index < currentIndex && styles['createWalletModal__step--completed'],
              index === currentIndex && styles['createWalletModal__step--active']
            )}
          >
            <div className={styles.createWalletModal__stepNumber}>{index + 1}</div>
            <span className={styles.createWalletModal__stepLabel}>{s.label}</span>
          </div>
        ))}
      </div>
    );
  };

  if (!isOpen) return null;

  return (
    <div className={styles.modalOverlay} onClick={handleCancel}>
      <div className={styles.createWalletModal} onClick={(e) => e.stopPropagation()}>
        <div className={styles.createWalletModal__header}>
          <h2 className={styles.createWalletModal__title}>创建共管钱包</h2>
          <button
            type="button"
            className={styles.createWalletModal__closeBtn}
            onClick={handleCancel}
            aria-label="关闭"
          >
            ×
          </button>
        </div>

        {renderStepIndicator()}

        <div className={styles.createWalletModal__content}>
          {step === 'config' && (
            <div className={styles.createWalletModal__form}>
              <div className={styles.createWalletModal__field}>
                <label className={styles.createWalletModal__label}>钱包名称</label>
                <input
                  type="text"
                  value={walletName}
                  onChange={(e) => setWalletName(e.target.value)}
                  placeholder="为您的共管钱包命名"
                  className={styles.createWalletModal__input}
                  disabled={isLoading}
                />
              </div>

              <div className={styles.createWalletModal__field}>
                <label className={styles.createWalletModal__label}>
                  阈值设置 (T-of-N)
                </label>
                <ThresholdConfig
                  thresholdT={thresholdT}
                  thresholdN={thresholdN}
                  onThresholdTChange={setThresholdT}
                  onThresholdNChange={setThresholdN}
                  disabled={isLoading}
                />
                <p className={styles.createWalletModal__hint}>
                  需要 {thresholdT} 个参与方共同签名才能执行交易
                </p>
              </div>

              <div className={styles.createWalletModal__field}>
                <label className={styles.createWalletModal__label}>您的名称</label>
                <input
                  type="text"
                  value={initiatorName}
                  onChange={(e) => setInitiatorName(e.target.value)}
                  placeholder="输入您的名称（其他参与者可见）"
                  className={styles.createWalletModal__input}
                  disabled={isLoading}
                />
              </div>

              {error && <p className={styles.createWalletModal__error}>{error}</p>}

              <div className={styles.createWalletModal__actions}>
                <button
                  type="button"
                  className={styles.createWalletModal__cancelBtn}
                  onClick={handleCancel}
                  disabled={isLoading}
                >
                  取消
                </button>
                <button
                  type="button"
                  className={styles.createWalletModal__submitBtn}
                  onClick={handleCreateSession}
                  disabled={isLoading}
                >
                  {isLoading ? '创建中...' : '创建会话'}
                </button>
              </div>
            </div>
          )}

          {step === 'invite' && session && (
            <div className={styles.createWalletModal__invite}>
              <InviteQRCode
                inviteCode={session.inviteCode}
                inviteUrl={session.inviteUrl}
              />

              <ParticipantList
                participants={session.participants}
                totalRequired={thresholdN}
              />

              {error && <p className={styles.createWalletModal__error}>{error}</p>}

              <div className={styles.createWalletModal__actions}>
                <button
                  type="button"
                  className={styles.createWalletModal__cancelBtn}
                  onClick={handleCancel}
                  disabled={isLoading}
                >
                  取消会话
                </button>
                <button
                  type="button"
                  className={styles.createWalletModal__submitBtn}
                  onClick={handleStartKeygen}
                  disabled={isLoading || session.participants.length < thresholdN}
                >
                  {isLoading
                    ? '启动中...'
                    : session.participants.length < thresholdN
                      ? `等待参与方 (${session.participants.length}/${thresholdN})`
                      : '开始生成密钥'}
                </button>
              </div>
            </div>
          )}

          {step === 'progress' && session && (
            <div className={styles.createWalletModal__progress}>
              <SessionProgress
                status={session.status}
                currentRound={session.currentRound}
                totalRounds={session.totalRounds}
                error={session.error}
              />

              <ParticipantList
                participants={session.participants}
                totalRequired={thresholdN}
              />
            </div>
          )}

          {step === 'result' && session && session.publicKey && (
            <WalletResult
              walletName={walletName}
              publicKey={session.publicKey}
              threshold={{ t: thresholdT, n: thresholdN }}
              participants={session.participants}
              createdAt={session.createdAt || new Date().toISOString()}
              onClose={onClose}
            />
          )}
        </div>

        {/* 密码输入对话框 */}
        {showPasswordDialog && (
          <div className={styles.passwordDialog}>
            <div className={styles.passwordDialog__content}>
              <h3 className={styles.passwordDialog__title}>设置密钥保护密码</h3>
              <p className={styles.passwordDialog__description}>
                请设置一个密码来加密您的密钥份额。此密码将用于保护您的本地密钥，
                签名交易时需要输入此密码。
              </p>
              <div className={styles.createWalletModal__field}>
                <label className={styles.createWalletModal__label}>密码</label>
                <input
                  type="password"
                  value={sharePassword}
                  onChange={(e) => setSharePassword(e.target.value)}
                  placeholder="至少 8 位字符"
                  className={styles.createWalletModal__input}
                  autoFocus
                />
              </div>
              {error && <p className={styles.createWalletModal__error}>{error}</p>}
              <div className={styles.createWalletModal__actions}>
                <button
                  type="button"
                  className={styles.createWalletModal__cancelBtn}
                  onClick={() => {
                    setShowPasswordDialog(false);
                    setSharePassword('');
                    setError(null);
                  }}
                >
                  取消
                </button>
                <button
                  type="button"
                  className={styles.createWalletModal__submitBtn}
                  onClick={handleConfirmKeygen}
                  disabled={!sharePassword || sharePassword.length < 8}
                >
                  确认并开始生成
                </button>
              </div>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}
