/**
 * 会话数据映射器
 * 负责 Conversation 模型与 API 响应、数据库记录之间的转换
 */

import {
  ConversationModel,
  ConversationType,
  UserModel,
  GroupModel,
  MessageModel,
} from '../models';
import type {
  ConversationResponse,
  ConversationDetailResponse,
  UserDTO,
  GroupResponse,
  MessageResponse,
} from '../../types/dto';
import { MessageMapper } from './MessageMapper';

// 数据库会话记录类型
export interface ConversationDbRecord {
  id: string;
  participantId: string;
  lastMessageId: string | null;
  lastSeq: number;
  unreadCount: number;
  createdAt: string;
  updatedAt: string;
}

// 缓存数据类型
export interface ConversationCacheData {
  id: string;
  type: string;
  is_pinned?: boolean;
  last_seq?: number;
  last_message?: any;
  last_message_at?: string;
  unread_count?: number;
  participants?: any[];
  my_last_read_seq?: number;
  other_last_read_seq?: number;
  group?: any;
  created_at?: string;
  updated_at?: string;
}

export class ConversationMapper {
  /**
   * 将 API 列表响应转换为应用模型
   */
  static fromApiResponse(response: ConversationResponse): ConversationModel {
    return {
      id: String(response.id || ''),
      type: (response.type as ConversationType) || 'private',
      participantId: this.extractParticipantId(response),
      lastMessageId: response.last_message?.id,
      lastMessage: response.last_message 
        ? MessageMapper.fromApiResponse(response.last_message)
        : undefined,
      lastSeq: response.last_seq || 0,
      myLastReadSeq: response.my_last_read_seq || 0,
      otherLastReadSeq: response.other_last_read_seq || 0,
      unreadCount: response.unread_count || 0,
      isPinned: response.is_pinned || false,
      participants: response.participants?.map(p => this.mapUserFromApi(p)),
      group: response.group ? this.mapGroupFromApi(response.group) : undefined,
      createdAt: new Date(response.created_at || Date.now()),
      updatedAt: new Date(response.updated_at || Date.now()),
    };
  }

  /**
   * 将 API 详情响应转换为应用模型
   */
  static fromDetailApiResponse(response: ConversationDetailResponse): ConversationModel {
    return {
      id: String(response.id || ''),
      type: (response.type as ConversationType) || 'private',
      participantId: this.extractParticipantIdFromDetail(response),
      lastMessageId: response.last_message?.id,
      lastMessage: response.last_message 
        ? MessageMapper.fromApiResponse(response.last_message)
        : undefined,
      lastSeq: response.last_seq || 0,
      myLastReadSeq: response.my_last_read_seq || 0,
      otherLastReadSeq: response.other_last_read_seq || 0,
      unreadCount: response.unread_count || 0,
      isPinned: response.is_pinned || false,
      participants: response.participants?.map(p => this.mapUserFromApi(p)),
      group: response.group ? this.mapGroupFromApi(response.group) : undefined,
      createdAt: new Date(response.created_at || Date.now()),
      updatedAt: new Date(response.updated_at || Date.now()),
    };
  }

  /**
   * 将 API 响应数组转换为应用模型数组
   */
  static fromApiResponseList(responses: ConversationResponse[]): ConversationModel[] {
    return responses.map(r => this.fromApiResponse(r));
  }

  /**
   * 从缓存数据转换为应用模型
   */
  static fromCacheData(id: string, cached: ConversationCacheData): ConversationModel {
    return {
      id: String(cached?.id || id),
      type: (cached?.type as ConversationType) || 'private',
      participantId: '',
      lastSeq: Number(cached?.last_seq || 0),
      lastMessage: cached?.last_message 
        ? MessageMapper.fromApiResponse(cached.last_message)
        : undefined,
      lastMessageId: cached?.last_message?.id,
      myLastReadSeq: Number(cached?.my_last_read_seq || 0),
      otherLastReadSeq: Number(cached?.other_last_read_seq || 0),
      unreadCount: Number(cached?.unread_count || 0),
      isPinned: Boolean(cached?.is_pinned),
      participants: Array.isArray(cached?.participants) 
        ? cached.participants.map(p => this.mapUserFromApi(p))
        : [],
      group: cached?.group ? this.mapGroupFromApi(cached.group) : undefined,
      createdAt: new Date(cached?.created_at || Date.now()),
      updatedAt: new Date(cached?.updated_at || Date.now()),
    };
  }

  /**
   * 将数据库记录转换为应用模型
   */
  static fromDbRecord(record: ConversationDbRecord): ConversationModel {
    return {
      id: record.id,
      type: 'private', // 数据库中不存储类型，需要额外查询
      participantId: record.participantId,
      lastMessageId: record.lastMessageId || undefined,
      lastSeq: record.lastSeq,
      myLastReadSeq: 0,
      otherLastReadSeq: 0,
      unreadCount: record.unreadCount,
      isPinned: false,
      createdAt: new Date(record.createdAt),
      updatedAt: new Date(record.updatedAt),
    };
  }

  /**
   * 将应用模型转换为数据库记录
   */
  static toDbRecord(model: ConversationModel): ConversationDbRecord {
    return {
      id: model.id,
      participantId: model.participantId,
      lastMessageId: model.lastMessageId || null,
      lastSeq: model.lastSeq,
      unreadCount: model.unreadCount,
      createdAt: model.createdAt.toISOString(),
      updatedAt: model.updatedAt.toISOString(),
    };
  }

  /**
   * 将应用模型转换为缓存数据
   */
  static toCacheData(model: ConversationModel): ConversationCacheData {
    return {
      id: model.id,
      type: model.type,
      is_pinned: model.isPinned,
      last_seq: model.lastSeq,
      last_message: model.lastMessage ? this.messageToCache(model.lastMessage) : undefined,
      last_message_at: model.updatedAt.toISOString(),
      unread_count: model.unreadCount,
      participants: model.participants?.map(p => this.userToCache(p)),
      my_last_read_seq: model.myLastReadSeq,
      other_last_read_seq: model.otherLastReadSeq,
      group: model.group ? this.groupToCache(model.group) : undefined,
      created_at: model.createdAt.toISOString(),
      updated_at: model.updatedAt.toISOString(),
    };
  }

  /**
   * 提取会话参与者 ID
   */
  private static extractParticipantId(response: ConversationResponse): string {
    if (response.participants && response.participants.length > 0) {
      return String(response.participants[0].id || '');
    }
    return '';
  }

  /**
   * 从详情响应提取参与者 ID
   */
  private static extractParticipantIdFromDetail(response: ConversationDetailResponse): string {
    if (response.participants && response.participants.length > 0) {
      return String(response.participants[0].id || '');
    }
    return '';
  }

  /**
   * 映射用户 API 响应
   */
  private static mapUserFromApi(user: UserDTO): UserModel {
    return {
      id: String(user.id || ''),
      username: user.username || '',
      nickname: user.nickname,
      avatar: user.avatar ?? undefined,
    };
  }

  /**
   * 映射群组 API 响应
   */
  private static mapGroupFromApi(group: GroupResponse): GroupModel {
    // 将数字类型的 join_type 转换为字符串类型
    // JoinType: 0 = 允许任何人, 1 = 需要审批, 2 = 不允许
    const mapJoinType = (joinType: number): 'anyone' | 'approval' | 'invite' => {
      switch (joinType) {
        case 0: return 'anyone';
        case 1: return 'approval';
        case 2: return 'invite';
        default: return 'approval';
      }
    };

    return {
      id: String(group.id || ''),
      name: group.name || '',
      avatar: group.avatar,
      description: group.description,
      // GroupResponse 没有 announcement 和 updated_at 字段，使用默认值
      announcement: undefined,
      ownerId: String(group.owner_id || ''),
      memberCount: group.member_count || 0,
      maxMemberCount: group.max_members || 500,
      joinType: mapJoinType(group.join_type),
      isMuted: group.mute_all || false,
      createdAt: new Date(group.created_at || Date.now()),
      updatedAt: new Date(group.created_at || Date.now()),
    };
  }

  /**
   * 消息模型转缓存格式
   */
  private static messageToCache(message: MessageModel): any {
    return {
      id: message.id,
      conversation_id: message.conversationId,
      sender_id: message.senderId,
      content: message.content,
      message_type: message.type,
      is_read: message.isRead,
      created_at: message.createdAt.toISOString(),
      seq: message.seq,
      status: message.status,
      segments: message.segments,
      reply_to_id: message.replyToId,
      sender: message.sender ? this.userToCache(message.sender) : undefined,
    };
  }

  /**
   * 用户模型转缓存格式
   */
  private static userToCache(user: UserModel): any {
    return {
      id: user.id,
      username: user.username,
      nickname: user.nickname,
      avatar: user.avatar,
    };
  }

  /**
   * 群组模型转缓存格式
   */
  private static groupToCache(group: GroupModel): any {
    return {
      id: group.id,
      name: group.name,
      avatar: group.avatar,
      description: group.description,
      announcement: group.announcement,
      owner_id: group.ownerId,
      member_count: group.memberCount,
      max_member_count: group.maxMemberCount,
      join_type: group.joinType,
      mute_all: group.isMuted,
      created_at: group.createdAt.toISOString(),
      updated_at: group.updatedAt.toISOString(),
    };
  }
}
