/**
 * Account Service HTTP Client
 *
 * 用于 Service-Party-App 调用 Account 服务的 HTTP API
 * 主要用于创建/查询 keygen 和 sign 会话
 */

// =============================================================================
// 类型定义
// =============================================================================

// Keygen 会话相关
export interface CreateKeygenSessionRequest {
  wallet_name: string;
  threshold_t: number;
  threshold_n: number;
  initiator_party_id: string;
  initiator_name?: string;
  persistent_count: number;
  external_count: number;
  expires_in_seconds?: number;
}

export interface CreateKeygenSessionResponse {
  session_id: string;
  invite_code: string;
  wallet_name: string;
  threshold_n: number;
  threshold_t: number;
  selected_server_parties: string[];
  join_tokens: Record<string, string>;
  join_token?: string; // Wildcard token for backward compatibility
  expires_at: number;
}

export interface JoinSessionRequest {
  party_id: string;
  join_token: string;
  device_type?: string;
  device_id?: string;
}

export interface PartyInfo {
  party_id: string;
  party_index: number;
}

export interface SessionInfo {
  session_id: string;
  session_type: string;
  threshold_n: number;
  threshold_t: number;
  status: string;
  wallet_name: string;
  invite_code: string;
  keygen_session_id?: string;
}

export interface JoinSessionResponse {
  success: boolean;
  party_index: number;
  session_info: SessionInfo;
  other_parties: PartyInfo[];
}

// Participant status information with party_index
export interface ParticipantStatusInfo {
  party_id: string;
  party_index: number;
  status: string;
}

export interface GetSessionStatusResponse {
  session_id: string;
  status: string;
  threshold_t: number;  // Minimum parties needed to sign (e.g., 2 in 2-of-3)
  threshold_n: number;  // Total number of parties required (e.g., 3 in 2-of-3)
  completed_parties: number;
  total_parties: number;
  session_type: string;
  public_key?: string;
  signature?: string;
  has_delegate: boolean;
  // participants contains detailed participant information including party_index
  // Used for co_managed_keygen sessions to build correct participant list
  participants?: ParticipantStatusInfo[];
}

export interface GetSessionByInviteCodeResponse {
  session_id: string;
  wallet_name: string;
  threshold_n: number;
  threshold_t: number;
  status: string;
  invite_code: string;
  expires_at: number;
  joined_parties: number;
  completed_parties?: number;
  total_parties?: number;
  join_token?: string;
}

// Sign 会话相关
export interface SignPartyInfo {
  party_id: string;
  party_index: number;
}

export interface CreateSignSessionRequest {
  keygen_session_id: string;
  wallet_name: string;
  message_hash: string;
  parties: SignPartyInfo[];
  threshold_t: number;
  initiator_name?: string;
}

export interface CreateSignSessionResponse {
  session_id: string;
  invite_code: string;
  keygen_session_id: string;
  wallet_name: string;
  threshold_t: number;
  selected_parties: string[];
  expires_at: number;
  join_token?: string; // Backward compatible: wildcard token (may be empty)
  join_tokens: Record<string, string>; // New: all join tokens (map[partyID]token)
}

export interface GetSignSessionByInviteCodeResponse {
  session_id: string;
  keygen_session_id: string;
  wallet_name: string;
  message_hash: string;
  threshold_t: number;
  threshold_n: number;
  status: string;
  invite_code: string;
  expires_at: number;
  parties: SignPartyInfo[];
  joined_count: number;
  join_token?: string;
}

export interface GetSignSessionStatusResponse {
  session_id: string;
  status: string;
  session_type: string;
  threshold_t: number;
  threshold_n: number;
  completed_parties: number;
  total_parties: number;
  joined_count?: number;
  parties?: SignPartyInfo[];
  participants?: Array<{ party_id: string; party_index: number; status: string }>;
  message_hash?: string;
  signature?: string;
}

// 错误响应
export interface ErrorResponse {
  error: string;
  message?: string;
}

// =============================================================================
// HTTP 客户端类
// =============================================================================

export class AccountClient {
  private baseUrl: string;
  private timeout: number;

  /**
   * 构造函数
   * @param baseUrl Account 服务的基础 URL (例如: https://api.szaiai.com 或 http://localhost:8080)
   * @param timeout 请求超时时间 (毫秒)
   */
  constructor(baseUrl: string, timeout: number = 30000) {
    // 移除末尾的斜杠
    this.baseUrl = baseUrl.replace(/\/$/, '');
    this.timeout = timeout;
  }

  /**
   * 更新基础 URL
   */
  setBaseUrl(baseUrl: string): void {
    this.baseUrl = baseUrl.replace(/\/$/, '');
  }

  /**
   * 获取当前基础 URL
   */
  getBaseUrl(): string {
    return this.baseUrl;
  }

  /**
   * 发送 HTTP 请求
   */
  private async request<T>(
    method: 'GET' | 'POST' | 'PUT' | 'DELETE',
    path: string,
    body?: unknown
  ): Promise<T> {
    const url = `${this.baseUrl}${path}`;

    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), this.timeout);

    try {
      const options: RequestInit = {
        method,
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json',
        },
        signal: controller.signal,
      };

      if (body) {
        options.body = JSON.stringify(body);
      }

      console.log(`[AccountClient] ${method} ${url}`, body ? JSON.stringify(body) : '');

      const response = await fetch(url, options);

      const text = await response.text();
      let data: T | ErrorResponse;

      try {
        data = JSON.parse(text);
      } catch {
        throw new Error(`Invalid JSON response: ${text}`);
      }

      if (!response.ok) {
        const errorData = data as ErrorResponse;
        throw new Error(errorData.message || errorData.error || `HTTP ${response.status}`);
      }

      console.log(`[AccountClient] Response:`, data);
      return data as T;
    } catch (error) {
      if (error instanceof Error && error.name === 'AbortError') {
        throw new Error(`Request timeout after ${this.timeout}ms`);
      }
      throw error;
    } finally {
      clearTimeout(timeoutId);
    }
  }

  // ===========================================================================
  // Keygen 会话 API
  // ===========================================================================

  /**
   * 创建 Keygen 会话
   */
  async createKeygenSession(
    params: CreateKeygenSessionRequest
  ): Promise<CreateKeygenSessionResponse> {
    return this.request<CreateKeygenSessionResponse>(
      'POST',
      '/api/v1/co-managed/sessions',
      params
    );
  }

  /**
   * 加入会话
   */
  async joinSession(
    sessionId: string,
    params: JoinSessionRequest
  ): Promise<JoinSessionResponse> {
    return this.request<JoinSessionResponse>(
      'POST',
      `/api/v1/co-managed/sessions/${sessionId}/join`,
      params
    );
  }

  /**
   * 获取会话状态
   */
  async getSessionStatus(sessionId: string): Promise<GetSessionStatusResponse> {
    return this.request<GetSessionStatusResponse>(
      'GET',
      `/api/v1/co-managed/sessions/${sessionId}`
    );
  }

  /**
   * 通过邀请码查询 Keygen 会话
   */
  async getSessionByInviteCode(inviteCode: string): Promise<GetSessionByInviteCodeResponse> {
    return this.request<GetSessionByInviteCodeResponse>(
      'GET',
      `/api/v1/co-managed/sessions/by-invite-code/${inviteCode}`
    );
  }

  // ===========================================================================
  // Sign 会话 API
  // ===========================================================================

  /**
   * 创建 Sign 会话
   */
  async createSignSession(
    params: CreateSignSessionRequest
  ): Promise<CreateSignSessionResponse> {
    return this.request<CreateSignSessionResponse>(
      'POST',
      '/api/v1/co-managed/sign',
      params
    );
  }

  /**
   * 通过邀请码查询 Sign 会话
   */
  async getSignSessionByInviteCode(inviteCode: string): Promise<GetSignSessionByInviteCodeResponse> {
    return this.request<GetSignSessionByInviteCodeResponse>(
      'GET',
      `/api/v1/co-managed/sign/by-invite-code/${inviteCode}`
    );
  }

  /**
   * 获取 Sign 会话状态
   */
  async getSignSessionStatus(sessionId: string): Promise<GetSignSessionStatusResponse> {
    return this.request<GetSignSessionStatusResponse>(
      'GET',
      `/api/v1/co-managed/sign/${sessionId}`
    );
  }

  // ===========================================================================
  // 健康检查
  // ===========================================================================

  /**
   * 健康检查
   */
  async healthCheck(): Promise<{ status: string; service: string }> {
    return this.request<{ status: string; service: string }>(
      'GET',
      '/health'
    );
  }

  /**
   * 测试连接
   */
  async testConnection(): Promise<boolean> {
    try {
      const result = await this.healthCheck();
      return result.status === 'healthy';
    } catch {
      return false;
    }
  }
}

// =============================================================================
// 默认实例
// =============================================================================

// 默认使用生产环境地址
const DEFAULT_ACCOUNT_SERVICE_URL = 'https://rwaapi.szaiai.com';

// 创建默认客户端实例
export const accountClient = new AccountClient(DEFAULT_ACCOUNT_SERVICE_URL);
