import { logger } from '../utils/logger';
import CryptoJS from 'crypto-js';

// 根据环境动态设置 API 基础 URL
const isDev = import.meta.env.DEV;
const API_BASE_URL = isDev 
  ? '/api/v1'  // 开发环境：使用相对路径，通过 Vite 代理
  : 'https://api.hnyunzhu.com/api/v1';  // 生产环境：使用完整 URL

const APP_ID = 101;

export interface LoginResponse {
  access_token: string;
  token_type: string;
  user?: {
    id: number;
    mobile: string;
    name?: string;
    [key: string]: any;
  };
}

export interface MessageResponse {
  id: number;
  type: 'MESSAGE' | 'NOTIFICATION';
  content_type: 'TEXT' | 'IMAGE' | 'VIDEO' | 'FILE' | 'USER_NOTIFICATION';
  content: string;
  title?: string;
  action_url?: string;
  action_text?: string;
  created_at: string;
  sender_id?: number;
  receiver_id?: number;
  app_user_id?: string;
  app_id?: number;
  size?: number;
}

export interface ContactResponse {
  id: number;
  name: string;
  avatar?: string;
  mobile?: string;
  last_message?: string;
  last_message_time?: string;
  unread_count?: number;
  remarks?: string | null;
}

export interface UserContact {
  id: number;
  mobile: string;
  name?: string;
  english_name?: string;
  status?: string;
}

export interface UserListResponse {
  total: number;
  items: UserContact[];
}

export interface AppMapping {
  app_name: string;
  app_id: string;
  protocol_type: 'SIMPLE_API' | 'OIDC';
  mapped_key: string;
  mapped_email: string | null;
  is_active: boolean;
  description: string | null;
  category_id: number | null;
  category_name: string | null;
}

export interface AppMappingListResponse {
  total: number;
  items: AppMapping[];
}

export interface SsoLoginResponse {
  redirect_url: string;
}

export interface MessagesListResponse {
  results: MessageResponse[];
  count: number;
  next?: string;
  previous?: string;
}

// 应用签名认证配置（如果需要从环境变量或配置读取）
interface AppAuthConfig {
  appId: number;
  secret: string;
}

/**
 * 生成应用签名
 * sign = HMAC-SHA256(secret, app_id=101×tamp=1700000000)
 */
function generateAppSignature(secret: string, appId: number, timestamp: number): string {
  const message = `app_id=${appId}&timestamp=${timestamp}`;
  return CryptoJS.HmacSHA256(message, secret).toString(CryptoJS.enc.Hex);
}

/**
 * 解析 JWT Token，提取用户信息
 * @param token JWT token
 * @returns 解析后的 payload，如果解析失败返回 null
 */
function parseJWT(token: string): any {
  try {
    const parts = token.split('.');
    if (parts.length !== 3) {
      logger.warn('API: Invalid JWT format');
      return null;
    }
    
    const base64Url = parts[1];
    const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
    const jsonPayload = decodeURIComponent(
      atob(base64)
        .split('')
        .map(function(c) {
          return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
        })
        .join('')
    );
    return JSON.parse(jsonPayload);
  } catch (e) {
    logger.error('API: Failed to parse JWT', e);
    return null;
  }
}

/**
 * 从 JWT token 中提取用户ID
 * @param token JWT token
 * @returns 用户ID，如果无法提取返回 null
 */
function getUserIdFromToken(token: string): number | null {
  const payload = parseJWT(token);
  if (!payload) {
    return null;
  }
  
  // 尝试多种可能的字段名
  const userId = payload.sub || payload.user_id || payload.id || payload.userId;
  if (userId) {
    const id = typeof userId === 'number' ? userId : parseInt(userId);
    if (!isNaN(id)) {
      logger.info('API: Extracted user ID from token', { userId: id });
      return id;
    }
  }
  
  logger.warn('API: Could not find user ID in token payload', payload);
  return null;
}

export const api = {
  // Login with mobile and password
  login: async (mobile: string, password: string): Promise<LoginResponse> => {
    const url = `${API_BASE_URL}/auth/login/json`;
    
    logger.info('API: Login request started', { 
      url,
      method: 'POST',
      mobile,
      hasPassword: !!password,
      rememberMe: true
    });
    
    const startTime = Date.now();
    
    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          mobile,
          password,
          remember_me: true
        })
      });

      const duration = Date.now() - startTime;
      const responseStatus = response.status;
      const responseHeaders: Record<string, string> = {};
      response.headers.forEach((value, key) => {
        responseHeaders[key] = value;
      });

      logger.info('API: Login response received', {
        url,
        status: responseStatus,
        statusText: response.statusText,
        duration: `${duration}ms`,
        headers: responseHeaders
      });

      if (!response.ok) {
        let errorData: any = {};
        try {
          errorData = await response.json();
        } catch (e) {
          const text = await response.text().catch(() => '');
          logger.warn('API: Login failed - unable to parse error response', {
            url,
            status: responseStatus,
            responseText: text.substring(0, 500) // 限制长度
          });
          throw new Error('登录失败，请检查账号密码');
        }
        
        logger.error('API: Login failed', {
          url,
          status: responseStatus,
          statusText: response.statusText,
          error: errorData,
          duration: `${duration}ms`,
          mobile
        });
        
        throw new Error(errorData.detail || errorData.message || '登录失败，请检查账号密码');
      }

      const responseData = await response.json();
      logger.info('API: Login successful', {
        url,
        status: responseStatus,
        duration: `${duration}ms`,
        mobile,
        hasToken: !!responseData.access_token,
        hasUser: !!responseData.user,
        userId: responseData.user?.id
      });

      return responseData;
    } catch (error) {
      const duration = Date.now() - startTime;
      
      if (error instanceof Error && error.message.includes('登录失败')) {
        // 已经记录过错误，直接抛出
        throw error;
      }
      
      // 网络错误或其他异常
      logger.error('API: Login request failed with exception', {
        url,
        error: error instanceof Error ? {
          name: error.name,
          message: error.message,
          stack: error.stack
        } : String(error),
        duration: `${duration}ms`,
        mobile
      });
      
      throw error;
    }
  },

  // 新增：发送短信验证码
  sendSmsCode: async (mobile: string): Promise<void> => {
    const url = `${API_BASE_URL}/auth/sms/send-code`;
    const requestBody = { mobile, platform: 'pc' };
    
    logger.info('API: Send SMS code request started', { 
      url,
      method: 'POST',
      mobile,
      platform: 'pc'
    });
    
    const startTime = Date.now();
    
    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(requestBody)
      });

      const duration = Date.now() - startTime;
      const responseStatus = response.status;

      logger.info('API: Send SMS code response received', {
        url,
        status: responseStatus,
        statusText: response.statusText,
        duration: `${duration}ms`
      });

      if (!response.ok) {
        let errorData: any = {};
        try {
          errorData = await response.json();
        } catch (e) {
          const text = await response.text().catch(() => '');
          logger.warn('API: Send SMS code failed - unable to parse error response', {
            url,
            status: responseStatus,
            responseText: text.substring(0, 500)
          });
          throw new Error('验证码发送失败');
        }
        
        logger.error('API: Send SMS code failed', {
          url,
          status: responseStatus,
          statusText: response.statusText,
          error: errorData,
          duration: `${duration}ms`,
          mobile
        });
        
        throw new Error(errorData.detail || errorData.message || '验证码发送失败');
      }

      logger.info('API: Send SMS code successful', {
        url,
        status: responseStatus,
        duration: `${duration}ms`,
        mobile
      });
    } catch (error) {
      const duration = Date.now() - startTime;
      
      if (error instanceof Error && error.message.includes('验证码发送失败')) {
        throw error;
      }
      
      logger.error('API: Send SMS code request failed with exception', {
        url,
        error: error instanceof Error ? {
          name: error.name,
          message: error.message,
          stack: error.stack
        } : String(error),
        duration: `${duration}ms`,
        mobile
      });
      
      throw error;
    }
  },

  // 新增：短信验证码登录
  loginBySms: async (mobile: string, code: string): Promise<LoginResponse> => {
    const url = `${API_BASE_URL}/auth/sms/login`;
    
    logger.info('API: SMS Login request started', { 
      url,
      method: 'POST',
      mobile,
      hasCode: !!code,
      codeLength: code.length,
      platform: 'pc'
    });
    
    const startTime = Date.now();
    
    try {
      const response = await fetch(url, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ mobile, code, platform: 'pc' })
      });

      const duration = Date.now() - startTime;
      const responseStatus = response.status;
      const responseHeaders: Record<string, string> = {};
      response.headers.forEach((value, key) => {
        responseHeaders[key] = value;
      });

      logger.info('API: SMS Login response received', {
        url,
        status: responseStatus,
        statusText: response.statusText,
        duration: `${duration}ms`,
        headers: responseHeaders
      });

      if (!response.ok) {
        let errorData: any = {};
        try {
          errorData = await response.json();
        } catch (e) {
          const text = await response.text().catch(() => '');
          logger.warn('API: SMS Login failed - unable to parse error response', {
            url,
            status: responseStatus,
            responseText: text.substring(0, 500)
          });
          throw new Error('验证码错误或已过期');
        }
        
        logger.error('API: SMS Login failed', {
          url,
          status: responseStatus,
          statusText: response.statusText,
          error: errorData,
          duration: `${duration}ms`,
          mobile
        });
        
        throw new Error(errorData.detail || errorData.message || '验证码错误或已过期');
      }

      const responseData = await response.json();
      logger.info('API: SMS Login successful', {
        url,
        status: responseStatus,
        duration: `${duration}ms`,
        mobile,
        hasToken: !!responseData.access_token,
        hasUser: !!responseData.user,
        userId: responseData.user?.id
      });

      return responseData;
    } catch (error) {
      const duration = Date.now() - startTime;
      
      if (error instanceof Error && (error.message.includes('验证码错误') || error.message.includes('验证码已过期'))) {
        throw error;
      }
      
      logger.error('API: SMS Login request failed with exception', {
        url,
        error: error instanceof Error ? {
          name: error.name,
          message: error.message,
          stack: error.stack
        } : String(error),
        duration: `${duration}ms`,
        mobile
      });
      
      throw error;
    }
  },

  /**
   * 获取当前用户信息（优先使用 /users/me 接口）
   * @param token 用户 Token
   */
  getCurrentUserInfo: async (token: string): Promise<{ id: number; [key: string]: any } | null> => {
    logger.info('API: Getting current user info started', {
      tokenLength: token.length,
      tokenPrefix: token.substring(0, 20) + '...'
    });
    
    // 优先调用 /users/me 接口
    const primaryUrl = `${API_BASE_URL}/users/me`;
    const startTime = Date.now();
    
    try {
      logger.info('API: Trying /users/me endpoint', { url: primaryUrl, method: 'GET' });
      
      const response = await fetch(primaryUrl, {
        method: 'GET',
        headers: {
          'Authorization': `Bearer ${token}`
        }
      });
      
      const duration = Date.now() - startTime;
      
      logger.info('API: /users/me response received', {
        url: primaryUrl,
        status: response.status,
        statusText: response.statusText,
        duration: `${duration}ms`
      });
      
      if (response.ok) {
        const userInfo = await response.json();
        if (userInfo && (userInfo.id || userInfo.user_id)) {
          const userId = userInfo.id || userInfo.user_id;
          logger.info('API: Got user info from /users/me', { 
            url: primaryUrl,
            userId, 
            userName: userInfo.name || userInfo.full_name || userInfo.username,
            duration: `${duration}ms`,
            userInfoKeys: Object.keys(userInfo)
          });
          return { id: userId, ...userInfo };
        } else {
          logger.warn('API: /users/me returned invalid data', { 
            url: primaryUrl,
            response: userInfo,
            duration: `${duration}ms`
          });
        }
      } else {
        let errorData: any = {};
        try {
          errorData = await response.json();
        } catch (e) {
          const text = await response.text().catch(() => '');
          logger.warn('API: /users/me returned non-ok status', { 
            url: primaryUrl,
            status: response.status,
            statusText: response.statusText,
            responseText: text.substring(0, 500),
            duration: `${duration}ms`
          });
        }
        if (Object.keys(errorData).length > 0) {
          logger.warn('API: /users/me error details', {
            url: primaryUrl,
            status: response.status,
            error: errorData,
            duration: `${duration}ms`
          });
        }
      }
    } catch (error) {
      const duration = Date.now() - startTime;
      logger.warn('API: Failed to get user info from /users/me', {
        url: primaryUrl,
        error: error instanceof Error ? {
          name: error.name,
          message: error.message,
          stack: error.stack
        } : String(error),
        duration: `${duration}ms`
      });
    }
    
    // 如果 /users/me 失败，尝试从 token 中解析
    logger.info('API: Trying to extract user ID from token');
    const userIdFromToken = getUserIdFromToken(token);
    if (userIdFromToken) {
      logger.info('API: Got user ID from token as fallback', { userId: userIdFromToken });
      return { id: userIdFromToken };
    } else {
      logger.warn('API: Could not extract user ID from token');
    }
    
    // 最后尝试其他可能的接口
    const possibleEndpoints = [
      '/auth/me',
      '/user/info',
      '/auth/user'
    ];
    
    for (const endpoint of possibleEndpoints) {
      const url = `${API_BASE_URL}${endpoint}`;
      const startTime = Date.now();
      
      try {
        logger.info(`API: Trying alternative endpoint ${endpoint}`, { url, method: 'GET' });
        
        const response = await fetch(url, {
          method: 'GET',
          headers: {
            'Authorization': `Bearer ${token}`
          }
        });
        
        const duration = Date.now() - startTime;
        
        logger.info(`API: ${endpoint} response received`, {
          url,
          status: response.status,
          statusText: response.statusText,
          duration: `${duration}ms`
        });
        
        if (response.ok) {
          const userInfo = await response.json();
          if (userInfo && (userInfo.id || userInfo.user_id)) {
            const userId = userInfo.id || userInfo.user_id;
            logger.info(`API: Got user info from ${endpoint}`, { 
              url,
              endpoint, 
              userId,
              userName: userInfo.name || userInfo.full_name || userInfo.username,
              duration: `${duration}ms`
            });
            return { id: userId, ...userInfo };
          } else {
            logger.warn(`API: ${endpoint} returned invalid data`, {
              url,
              response: userInfo,
              duration: `${duration}ms`
            });
          }
        } else {
          logger.warn(`API: ${endpoint} returned non-ok status`, {
            url,
            status: response.status,
            statusText: response.statusText,
            duration: `${duration}ms`
          });
        }
      } catch (error) {
        const duration = Date.now() - startTime;
        logger.warn(`API: Failed to get user info from ${endpoint}`, {
          url,
          error: error instanceof Error ? {
            name: error.name,
            message: error.message
          } : String(error),
          duration: `${duration}ms`
        });
        // 继续尝试下一个接口
      }
    }
    
    logger.warn('API: Could not get user info from any source');
    return null;
  },

  /**
   * 从 JWT token 中获取用户ID（工具方法）
   */
  getUserIdFromToken: (token: string): number | null => {
    return getUserIdFromToken(token);
  },

  /**
   * 用户调用：发送私信（Token 认证）
   * 适用于用户在前端直接发送私信
   */
  sendMessage: async (
    token: string, 
    receiverId: number, 
    content: string, 
    contentType: 'TEXT' | 'IMAGE' | 'VIDEO' | 'FILE' = 'TEXT',
    title?: string  // 添加可选的 title 参数
  ): Promise<MessageResponse> => {
    logger.info('API: Send message (user)', { receiverId, contentType, content, title });
    const response = await fetch(`${API_BASE_URL}/messages/`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`
      },
      body: JSON.stringify({
        receiver_id: receiverId,
        type: 'MESSAGE',
        content_type: contentType,
        title: title || '私信',  // 使用传入的 title，如果没有则默认为'私信'
        content
      })
    });

    if (!response.ok) {
      const error = await response.json().catch(() => ({}));
      logger.error('API: Send message failed', { status: response.status, error });
      throw new Error(error.detail || '发送消息失败');
    }

    return response.json();
  },

  /**
   * 发送与历史 USER_NOTIFICATION 同结构的消息（再次提醒）
   */
  sendUserNotificationMessage: async (
    token: string,
    options: {
      receiverId: number;
      title: string;
      content: string;
      actionUrl?: string;
      actionText?: string;
      appId?: number;
    }
  ): Promise<MessageResponse> => {
    const {
      receiverId,
      title,
      content,
      actionUrl,
      actionText,
      appId
    } = options;
    logger.info('API: Send USER_NOTIFICATION message', { receiverId, title });
    const body: Record<string, unknown> = {
      receiver_id: receiverId,
      type: 'MESSAGE',
      content_type: 'USER_NOTIFICATION',
      title,
      content
    };
    if (actionUrl != null && actionUrl !== '') {
      body.action_url = actionUrl;
    }
    if (actionText != null && actionText !== '') {
      body.action_text = actionText;
    }
    if (appId != null) {
      body.app_id = appId;
    }

    const response = await fetch(`${API_BASE_URL}/messages/`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${token}`
      },
      body: JSON.stringify(body)
    });

    if (!response.ok) {
      const error = await response.json().catch(() => ({}));
      logger.error('API: Send USER_NOTIFICATION failed', { status: response.status, error });
      const detail = (error as { detail?: unknown }).detail;
      const msg =
        typeof detail === 'string'
          ? detail
          : Array.isArray(detail)
            ? detail.map((d: unknown) => (typeof d === 'object' && d && 'msg' in d ? String((d as { msg: string }).msg) : String(d))).join('; ')
            : '发送失败';
      throw new Error(msg || '发送失败');
    }

    return response.json();
  },

  /**
   * 应用调用：发送通知（签名认证）
   * 适用于业务系统后端向用户推送通知
   * 注意：此方法需要应用密钥，通常在后端调用，前端仅作示例
   */
  sendNotification: async (
    config: AppAuthConfig,
    appUserId: string,
    options: {
      title: string;
      content: string;
      contentType?: 'TEXT' | 'IMAGE' | 'FILE';
      autoSso?: boolean;
      targetUrl?: string;
      actionText?: string;
    }
  ): Promise<MessageResponse> => {
    logger.info('API: Send notification (app)', { appUserId, title: options.title });
    
    const timestamp = Math.floor(Date.now() / 1000);
    const sign = generateAppSignature(config.secret, config.appId, timestamp);

    const response = await fetch(`${API_BASE_URL}/messages/`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-App-Id': String(config.appId),
        'X-Timestamp': String(timestamp),
        'X-Sign': sign
      },
      body: JSON.stringify({
        app_id: config.appId,
        app_user_id: appUserId,
        type: 'NOTIFICATION',
        content_type: options.contentType || 'TEXT',
        title: options.title,
        content: options.content,
        auto_sso: options.autoSso ?? true,
        target_url: options.targetUrl,
        action_text: options.actionText
      })
    });

    if (!response.ok) {
      const error = await response.json().catch(() => ({}));
      logger.error('API: Send notification failed', { status: response.status, error });
      throw new Error(error.detail || '发送通知失败');
    }

    return response.json();
  },

  /**
   * 获取聊天历史记录
   * @param token 用户 Token
   * @param otherUserId 对方用户ID（0 表示系统通知）
   * @param params 查询参数
   */
  getMessages: async (
    token: string,
    otherUserId: number,
    params?: {
      skip?: number;
      limit?: number;
    }
  ): Promise<MessageResponse[]> => {
    logger.info('API: Get messages history', { otherUserId, params });
    
    const skip = params?.skip || 0;
    const limit = params?.limit || 50;
    const url = `${API_BASE_URL}/messages/history/${otherUserId}?skip=${skip}&limit=${limit}`;
    
    const response = await fetch(url, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${token}`
      }
    });

    if (!response.ok) {
      const error = await response.json().catch(() => ({}));
      logger.error('API: Get messages failed', { status: response.status, error });
      throw new Error(error.detail || '获取消息列表失败');
    }

    return response.json();
  },

  /**
   * 获取通知/广播消息的可跳转链接（带 ticket 的 callback_url，用于 SSO 跳转）
   * @param token 用户 Token
   * @param messageId 消息ID
   */
  getMessageCallbackUrl: async (token: string, messageId: number): Promise<{ callback_url: string }> => {
    const response = await fetch(`${API_BASE_URL}/messages/${messageId}/callback-url`, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${token}`
      }
    });

    if (!response.ok) {
      const error = await response.json().catch(() => ({}));
      logger.error('API: Get message callback URL failed', { messageId, status: response.status, error });
      throw new Error(error.detail || '获取跳转链接失败');
    }

    return response.json();
  },

  /**
   * 获取当前用户未读消息总数
   */
  getUnreadCount: async (token: string): Promise<number> => {
    const response = await fetch(`${API_BASE_URL}/messages/unread-count`, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${token}`
      }
    });

    if (!response.ok) {
      const error = await response.json().catch(() => ({}));
      logger.error('API: Get unread count failed', { status: response.status, error });
      throw new Error(error.detail || '获取未读消息数失败');
    }

    const text = await response.text();
    const trimmed = text.trim();
    try {
      const parsed = JSON.parse(trimmed) as unknown;
      if (typeof parsed === 'number' && !Number.isNaN(parsed)) return parsed;
      if (typeof parsed === 'object' && parsed !== null && 'count' in (parsed as any)) {
        const n = Number((parsed as { count: unknown }).count);
        if (!Number.isNaN(n)) return n;
      }
    } catch {
      const n = parseInt(trimmed, 10);
      if (!Number.isNaN(n)) return n;
    }
    const n = parseInt(trimmed, 10);
    if (!Number.isNaN(n)) return n;
    throw new Error('无效的未读消息数响应');
  },

  /**
   * 按会话将当前用户作为接收方的未读消息全部标为已读
   */
  markConversationReadAll: async (token: string, otherUserId: number): Promise<{ updated_count: number }> => {
    const response = await fetch(`${API_BASE_URL}/messages/history/${otherUserId}/read-all`, {
      method: 'PUT',
      headers: {
        'Authorization': `Bearer ${token}`
      }
    });

    if (!response.ok) {
      const error = await response.json().catch(() => ({}));
      logger.error('API: Mark conversation read-all failed', { otherUserId, status: response.status, error });
      throw new Error(error.detail || '标记会话已读失败');
    }

    return response.json();
  },

  /**
   * 获取联系人列表（聊天会话列表）
   * @param token 用户 Token
   */
  getContacts: async (token: string): Promise<ContactResponse[]> => {
    logger.info('API: Get contacts');
    
    const response = await fetch(`${API_BASE_URL}/messages/conversations`, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${token}`
      }
    });

    if (!response.ok) {
      const error = await response.json().catch(() => ({}));
      logger.error('API: Get contacts failed', { status: response.status, error });
      throw new Error(error.detail || '获取联系人列表失败');
    }

    const data = await response.json();
    // 转换 API 返回格式为 ContactResponse 格式
    // API 返回格式: { user_id, username, full_name, unread_count, last_message, last_message_type, updated_at }
    return data.map((item: any) => ({
      id: item.user_id || 0,
      name: item.full_name || item.username || '未知用户',
      last_message: item.last_message,
      last_message_time: item.updated_at,
      unread_count: item.unread_count || 0,
      remarks: item.remarks ?? null
    }));
  },

  /**
   * 搜索联系人（普通用户接口，不支持分页）
   * @param token 用户 Token
   * @param keyword 搜索关键词（手机号/姓名/英文名）
   * @param limit 返回数量限制（默认50）
   */
  searchContacts: async (token: string, keyword: string = '', limit: number = 50): Promise<UserContact[]> => {
    logger.info('API: Search contacts', { keyword, limit });
    
    const params = new URLSearchParams();
    if (keyword) {
      params.append('q', keyword);
    }
    params.append('limit', String(limit));
    
    const response = await fetch(`${API_BASE_URL}/users/search?${params.toString()}`, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${token}`
      }
    });

    if (!response.ok) {
      const error = await response.json().catch(() => ({}));
      logger.error('API: Search contacts failed', { status: response.status, error });
      throw new Error(error.detail || '搜索联系人失败');
    }

    return response.json();
  },

  /**
   * 分页获取联系人列表（管理员接口，支持完整分页）
   * @param token 用户 Token
   * @param params 分页参数
   */
  getContactsPaginated: async (
    token: string,
    params: {
      skip?: number;
      limit?: number;
      keyword?: string;
      status?: string;
    }
  ): Promise<UserListResponse> => {
    logger.info('API: Get contacts paginated', params);
    
    const queryParams = new URLSearchParams();
    if (params.skip !== undefined) {
      queryParams.append('skip', String(params.skip));
    }
    if (params.limit !== undefined) {
      queryParams.append('limit', String(params.limit));
    }
    if (params.keyword) {
      queryParams.append('keyword', params.keyword);
    }
    if (params.status) {
      queryParams.append('status', params.status);
    }
    
    const response = await fetch(`${API_BASE_URL}/users/?${queryParams.toString()}`, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${token}`
      }
    });

    if (!response.ok) {
      const error = await response.json().catch(() => ({}));
      logger.error('API: Get contacts paginated failed', { status: response.status, error });
      // 如果是权限错误（403），抛出特殊错误以便前端降级处理
      if (response.status === 403) {
        throw new Error('PERMISSION_DENIED');
      }
      throw new Error(error.detail || '获取联系人列表失败');
    }

    return response.json();
  },

  /**
   * 获取我的账号映射列表
   * @param token 用户 Token
   * @param params 查询参数
   */
  getMyMappings: async (
    token: string,
    params?: {
      skip?: number;
      limit?: number;
      app_name?: string;
    }
  ): Promise<AppMappingListResponse> => {
    logger.info('API: Get my mappings', params);
    
    const queryParams = new URLSearchParams();
    if (params?.skip !== undefined) {
      queryParams.append('skip', String(params.skip));
    }
    if (params?.limit !== undefined) {
      queryParams.append('limit', String(params.limit));
    }
    if (params?.app_name) {
      queryParams.append('app_name', params.app_name);
    }
    
    const response = await fetch(`${API_BASE_URL}/simple/me/mappings?${queryParams.toString()}`, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      }
    });

    if (!response.ok) {
      const error = await response.json().catch(() => ({}));
      logger.error('API: Get my mappings failed', { status: response.status, error });
      throw new Error(error.detail || '获取账号映射列表失败');
    }

    return response.json();
  },

  /**
   * 获取启动台应用列表（含分类信息，用于应用中心展示）
   * @param token 用户 Token
   * @param params 查询参数
   */
  getLaunchpadApps: async (
    token: string,
    params?: {
      skip?: number;
      limit?: number;
      app_name?: string;
    }
  ): Promise<AppMappingListResponse> => {
    logger.info('API: Get launchpad apps', params);

    const queryParams = new URLSearchParams();
    if (params?.skip !== undefined) {
      queryParams.append('skip', String(params.skip));
    }
    if (params?.limit !== undefined) {
      queryParams.append('limit', String(params.limit));
    }
    if (params?.app_name) {
      queryParams.append('app_name', params.app_name);
    }

    const response = await fetch(`${API_BASE_URL}/simple/me/launchpad-apps?${queryParams.toString()}`, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      }
    });

    if (!response.ok) {
      const error = await response.json().catch(() => ({}));
      logger.error('API: Get launchpad apps failed', { status: response.status, error });
      throw new Error(error.detail || '获取应用列表失败');
    }

    return response.json();
  },

  /**
   * SSO 单点登录
   * @param token 用户 Token（可选，如果已登录）
   * @param appId 目标应用ID
   * @param username 用户名（可选，如果已登录可不提供）
   * @param password 密码（可选，如果已登录可不提供）
   */
  ssoLogin: async (
    token: string | null,
    appId: string,
    username?: string,
    password?: string
  ): Promise<SsoLoginResponse> => {
    logger.info('API: SSO login', { appId, hasToken: !!token, hasCredentials: !!(username && password) });
    
    const headers: Record<string, string> = {
      'Content-Type': 'application/json'
    };
    
    // 如果提供了 token，添加到请求头
    if (token) {
      headers['Authorization'] = `Bearer ${token}`;
    }
    
    const body: Record<string, string> = {
      app_id: appId
    };
    
    // 如果提供了用户名和密码，添加到请求体
    if (username && password) {
      body.username = username;
      body.password = password;
    }
    
    const response = await fetch(`${API_BASE_URL}/simple/sso-login`, {
      method: 'POST',
      headers,
      body: JSON.stringify(body)
    });

    if (!response.ok) {
      const error = await response.json().catch(() => ({}));
      logger.error('API: SSO login failed', { status: response.status, error });
      throw new Error(error.detail || 'SSO 登录失败');
    }

    return response.json();
  },

  /**
   * 上传文件（图片、视频、文档）
   * @param token 用户 Token
   * @param file 文件对象
   * @param onProgress 上传进度回调（可选）
   */
  uploadFile: async (
    token: string,
    file: File,
    onProgress?: (percent: number) => void
  ): Promise<{
    url: string;        // 预签名 URL（1小时有效）
    key: string;        // MinIO 对象键，用于存储到消息表
    filename: string;
    content_type: string;
    size: number;
  }> => {
    logger.info('API: Upload file', { filename: file.name, size: file.size });
    
    const formData = new FormData();
    formData.append('file', file);
    
    // 使用 XMLHttpRequest 以支持上传进度
    return new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest();
      
      // 上传进度
      if (onProgress) {
        xhr.upload.addEventListener('progress', (e) => {
          if (e.lengthComputable) {
            const percent = Math.round((e.loaded / e.total) * 100);
            onProgress(percent);
          }
        });
      }
      
      // 完成处理
      xhr.addEventListener('load', () => {
        if (xhr.status >= 200 && xhr.status < 300) {
          try {
            const result = JSON.parse(xhr.responseText);
            logger.info('API: Upload file success', { key: result.key });
            resolve(result);
          } catch (e) {
            logger.error('API: Parse upload response failed', e);
            reject(new Error('解析上传响应失败'));
          }
        } else {
          try {
            const error = JSON.parse(xhr.responseText);
            logger.error('API: Upload file failed', { status: xhr.status, error });
            reject(new Error(error.detail || '文件上传失败'));
          } catch (e) {
            reject(new Error(`上传失败: ${xhr.statusText}`));
          }
        }
      });
      
      // 错误处理
      xhr.addEventListener('error', () => {
        logger.error('API: Upload file network error');
        reject(new Error('网络错误，上传失败'));
      });
      
      // 发送请求
      xhr.open('POST', `${API_BASE_URL}/messages/upload`);
      xhr.setRequestHeader('Authorization', `Bearer ${token}`);
      xhr.send(formData);
    });
  },

  /**
   * 根据文件类型判断 content_type
   */
  getContentType: (file: File): 'IMAGE' | 'VIDEO' | 'FILE' => {
    if (file.type.startsWith('image/')) {
      return 'IMAGE';
    } else if (file.type.startsWith('video/')) {
      return 'VIDEO';
    } else {
      return 'FILE';
    }
  }
};
