/**
 * PostRepository - 帖子仓库实现
 * 实现IPostRepository接口，封装帖子相关的数据访问逻辑
 */

import { ApiDataSource, apiDataSource } from '../datasources/ApiDataSource';
import { LocalDataSource, localDataSource } from '../datasources/LocalDataSource';
import { PostMapper } from '../mappers/PostMapper';
import type { Post, PostImage, PostStatus } from '../../core/entities/Post';
import { createPost } from '../../core/entities/Post';
import type {
  IPostRepository,
  GetPostsParams,
  CreatePostData,
  UpdatePostData,
  PostsResult,
  SearchPostsParams,
} from './interfaces/IPostRepository';

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

/**
 * API帖子响应类型
 */
interface PostApiResponse {
  id: number;
  user_id: number;
  title: string;
  content: string;
  images?: Array<{ url: string; width?: number; height?: number; thumbnail_url?: string }>;
  likes_count: number;
  comments_count: number;
  shares_count: number;
  views_count: number;
  favorites_count: number;
  is_liked: boolean;
  is_favorited: boolean;
  is_pinned: boolean;
  status: string;
  channel_id?: string;
  tags?: string[];
  created_at: string;
  updated_at: string;
  content_edited_at?: string;
  channel?: { id: string; name: string } | null;
  author?: {
    id: number;
    username: string;
    nickname?: string;
    avatar?: string;
    is_following?: boolean;
    is_following_me?: boolean;
  };
}

/**
 * API帖子列表响应类型
 */
interface PostsListApiResponse {
  list: PostApiResponse[];
  has_more?: boolean;
  next_cursor?: string;
  total?: number;
  page?: number;
  page_size?: number;
  total_pages?: number;
}

/**
 * 缓存的帖子数据
 */
interface CachedPost {
  id: string;
  data: string;
  updatedAt: string;
}

// ==================== PostRepository 实现 ====================

export class PostRepository implements IPostRepository {
  private api: ApiDataSource;
  private localDb: LocalDataSource;
  private memoryCache: Map<string, { post: Post; timestamp: number }> = new Map();
  private readonly CACHE_TTL = 5 * 60 * 1000; // 5分钟缓存过期时间

  constructor(api: ApiDataSource, localDb: LocalDataSource) {
    this.api = api;
    this.localDb = localDb;
  }

  // ==================== 私有辅助方法 ====================

  /**
   * 将API响应转换为领域实体
   * 同时设置 camelCase 和 snake_case 字段以保持向后兼容
   */
  private mapToPost(response: PostApiResponse): Post {
    const model = PostMapper.fromApiResponse(response as any);
    return {
      // camelCase 字段（新标准）
      id: model.id,
      authorId: model.authorId,
      author: model.author ? {
        id: model.author.id,
        username: model.author.username,
        nickname: model.author.nickname,
        avatar: model.author.avatar,
        // 关注关系直接透传 API 字段，供详情页关注按钮状态使用
        is_following: response.author?.is_following,
        is_following_me: response.author?.is_following_me,
      } : undefined,
      title: model.title,
      content: model.content,
      images: (model.images || []).map(url => ({
        url,
        width: undefined,
        height: undefined,
      })) as PostImage[],
      likesCount: model.likeCount,
      commentsCount: model.commentCount,
      sharesCount: model.shareCount,
      viewsCount: model.viewCount,
      favoritesCount: model.favoriteCount,
      isLiked: model.isLiked,
      isFavorited: model.isFavorited,
      isPinned: model.isTop,
      status: model.status,
      channelId: model.channelId,
      channel: model.channel,
      tags: model.tags || [],
      createdAt: model.createdAt.toISOString(),
      updatedAt: model.updatedAt.toISOString(),
      contentEditedAt: response.content_edited_at,
      
      // snake_case 字段（向后兼容）
      likes_count: model.likeCount,
      comments_count: model.commentCount,
      favorites_count: model.favoriteCount,
      shares_count: model.shareCount,
      views_count: model.viewCount,
      is_liked: model.isLiked,
      is_favorited: model.isFavorited,
      is_pinned: model.isTop,
      user_id: model.authorId,
      created_at: model.createdAt.toISOString(),
      updated_at: model.updatedAt.toISOString(),
      content_edited_at: response.content_edited_at,
      channel_id: model.channelId,
    };
  }

  /**
   * 从内存缓存获取帖子
   */
  private getFromMemoryCache(id: string): Post | null {
    const cached = this.memoryCache.get(id);
    if (!cached) return null;

    // 检查缓存是否过期
    if (Date.now() - cached.timestamp > this.CACHE_TTL) {
      this.memoryCache.delete(id);
      return null;
    }

    return cached.post;
  }

  /**
   * 保存帖子到内存缓存
   */
  private saveToMemoryCache(post: Post): void {
    this.memoryCache.set(post.id, {
      post,
      timestamp: Date.now(),
    });
  }

  /**
   * 从本地数据库获取缓存的帖子
   */
  private async getFromLocalCache(id: string): Promise<Post | null> {
    try {
      await this.localDb.initialize();
      const result = await this.localDb.getFirst<CachedPost>(
        'SELECT * FROM posts_cache WHERE id = ?',
        [id]
      );

      if (!result) return null;

      const post = JSON.parse(result.data) as Post;
      return post;
    } catch (error) {
      console.error('[PostRepository] 获取本地缓存失败:', error);
      return null;
    }
  }

  /**
   * 保存帖子到本地缓存
   */
  private async saveToLocalCache(post: Post): Promise<void> {
    try {
      await this.localDb.initialize();
      await this.localDb.enqueueWrite(async () => {
        await this.localDb.run(
          `INSERT OR REPLACE INTO posts_cache (id, data, updatedAt) VALUES (?, ?, ?)`,
          [post.id, JSON.stringify(post), new Date().toISOString()]
        );
      });
    } catch (error) {
      console.error('[PostRepository] 保存本地缓存失败:', error);
    }
  }

  /**
   * 清除帖子的本地缓存
   */
  private async clearLocalCache(id: string): Promise<void> {
    try {
      await this.localDb.initialize();
      await this.localDb.enqueueWrite(async () => {
        await this.localDb.run('DELETE FROM posts_cache WHERE id = ?', [id]);
      });
    } catch (error) {
      console.error('[PostRepository] 清除本地缓存失败:', error);
    }
  }

  /**
   * 处理错误
   */
  private handleError(error: unknown, operation: string): never {
    const message = error instanceof Error ? error.message : 'Unknown error';
    console.error(`[PostRepository] ${operation} 失败:`, error);
    throw new Error(`帖子${operation}失败: ${message}`);
  }

  // ==================== 帖子查询 ====================

  /**
   * 获取帖子列表
   */
  async getPosts(params?: GetPostsParams): Promise<PostsResult> {
    try {
      const queryParams: Record<string, any> = {};

      if (params?.page !== undefined) queryParams.page = params.page;
      if (params?.pageSize) queryParams.page_size = params.pageSize;
      // 支持 cursor 参数：空字符串也传递，用于启动 cursor 模式
      if (params?.cursor !== undefined && params?.cursor !== null) {
        queryParams.cursor = params.cursor;
      }
      if (params?.post_type) queryParams.tab = params.post_type;
      if (params?.channelId) queryParams.channel_id = params.channelId;
      if (params?.authorId) queryParams.author_id = params.authorId;
      if (params?.tags && params.tags.length > 0) queryParams.tags = params.tags.join(',');
      if (params?.status) queryParams.status = params.status;
      if (params?.sortBy) queryParams.sort_by = params.sortBy;
      if (params?.sortOrder) queryParams.sort_order = params.sortOrder;
      if (params?.pinnedOnly) queryParams.pinned_only = true;

      const response = await this.api.get<PostsListApiResponse>('/posts', queryParams);

      const posts = (response.list || []).map(p => this.mapToPost(p));

      // 缓存帖子
      for (const post of posts) {
        this.saveToMemoryCache(post);
        // 不等待本地缓存写入完成，避免阻塞 UI
        this.saveToLocalCache(post).catch(err => {
          console.warn('[PostRepository] 缓存帖子失败:', post.id, err);
        });
      }

      // 计算 hasMore：优先使用 has_more，否则通过 page/total_pages 计算
      let hasMore = response.has_more;
      if (hasMore === undefined && response.page !== undefined && response.total_pages !== undefined) {
        hasMore = response.page < response.total_pages;
      }
      hasMore = hasMore ?? false;

      return {
        posts,
        hasMore,
        nextCursor: response.next_cursor,
        total: response.total,
      };
    } catch (error) {
      this.handleError(error, '获取帖子列表');
    }
  }

  /**
   * 获取单个帖子详情
   */
  async getPostById(id: string): Promise<Post | null> {
    try {
      // 详情页优先取最新服务端数据，避免旧缓存导致关注态等关系字段过期
      const response = await this.api.get<PostApiResponse>(`/posts/${id}`);
      const post = this.mapToPost(response);

      // 更新缓存
      this.saveToMemoryCache(post);
      await this.saveToLocalCache(post);

      return post;
    } catch (error) {
      // API失败时再回退缓存，保证离线/弱网可用
      const memoryCached = this.getFromMemoryCache(id);
      if (memoryCached) {
        console.warn('[PostRepository] API获取失败，使用内存缓存:', error);
        return memoryCached;
      }
      const localCached = await this.getFromLocalCache(id);
      if (localCached) {
        console.warn('[PostRepository] API获取失败，使用本地缓存:', error);
        this.saveToMemoryCache(localCached);
        return localCached;
      }
      this.handleError(error, '获取帖子详情');
    }
  }

  /**
   * 获取用户发布的帖子列表
   */
  async getPostsByUser(userId: string, params?: GetPostsParams): Promise<PostsResult> {
    try {
      const queryParams: Record<string, any> = { author_id: userId };

      if (params?.page) queryParams.page = params.page;
      if (params?.pageSize) queryParams.page_size = params.pageSize;
      if (params?.cursor) queryParams.cursor = params.cursor;
      if (params?.status) queryParams.status = params.status;
      if (params?.sortBy) queryParams.sort_by = params.sortBy;
      if (params?.sortOrder) queryParams.sort_order = params.sortOrder;

      const response = await this.api.get<PostsListApiResponse>(`/users/${userId}/posts`, queryParams);

      const posts = (response.list || []).map(p => this.mapToPost(p));

      // 缓存帖子
      for (const post of posts) {
        this.saveToMemoryCache(post);
        this.saveToLocalCache(post).catch(err => {
          console.warn('[PostRepository] 缓存帖子失败:', post.id, err);
        });
      }

      return {
        posts,
        hasMore: response.has_more ?? false,
        nextCursor: response.next_cursor,
        total: response.total,
      };
    } catch (error) {
      this.handleError(error, '获取用户帖子列表');
    }
  }

  /**
   * 搜索帖子
   */
  async searchPosts(params: SearchPostsParams): Promise<PostsResult> {
    try {
      const queryParams: Record<string, any> = {
        keyword: params.keyword,
      };

      if (params.page) queryParams.page = params.page;
      if (params.pageSize) queryParams.page_size = params.pageSize;
      if (params.scope) queryParams.scope = params.scope;
      if (params.channelId) queryParams.channel_id = params.channelId;

      const response = await this.api.get<PostsListApiResponse>('/posts/search', queryParams);

      const posts = (response.list || []).map(p => this.mapToPost(p));

      // 缓存帖子
      for (const post of posts) {
        this.saveToMemoryCache(post);
        this.saveToLocalCache(post).catch(err => {
          console.warn('[PostRepository] 缓存帖子失败:', post.id, err);
        });
      }

      return {
        posts,
        hasMore: response.has_more ?? false,
        nextCursor: response.next_cursor,
        total: response.total,
      };
    } catch (error) {
      this.handleError(error, '搜索帖子');
    }
  }

  // ==================== 帖子操作 ====================

  /**
   * 创建帖子
   */
  async createPost(data: CreatePostData): Promise<Post> {
    try {
      const requestData = PostMapper.createPostRequest(
        data.title,
        data.content,
        data.images?.map(img => img.url),
        data.channelId
      );

      if (data.tags && data.tags.length > 0) {
        requestData.tags = data.tags;
      }

      if (data.status) {
        requestData.status = data.status;
      }

      const response = await this.api.post<PostApiResponse>('/posts', requestData);
      const post = this.mapToPost(response);

      // 缓存新创建的帖子
      this.saveToMemoryCache(post);
      await this.saveToLocalCache(post);

      return post;
    } catch (error) {
      this.handleError(error, '创建帖子');
    }
  }

  /**
   * 更新帖子
   */
  async updatePost(id: string, data: UpdatePostData): Promise<Post> {
    try {
      const requestData: Record<string, any> = {};

      if (data.title !== undefined) requestData.title = data.title;
      if (data.content !== undefined) requestData.content = data.content;
      if (data.images !== undefined) requestData.images = data.images.map(img => img.url);
      if (data.tags !== undefined) requestData.tags = data.tags;
      if (data.status !== undefined) requestData.status = data.status;
      if (data.isPinned !== undefined) requestData.is_pinned = data.isPinned;

      const response = await this.api.put<PostApiResponse>(`/posts/${id}`, requestData);
      const post = this.mapToPost(response);

      // 更新缓存
      this.saveToMemoryCache(post);
      await this.saveToLocalCache(post);

      return post;
    } catch (error) {
      this.handleError(error, '更新帖子');
    }
  }

  /**
   * 删除帖子
   */
  async deletePost(id: string): Promise<void> {
    try {
      await this.api.delete(`/posts/${id}`);

      // 清除缓存
      this.memoryCache.delete(id);
      await this.clearLocalCache(id);
    } catch (error) {
      this.handleError(error, '删除帖子');
    }
  }

  // ==================== 互动操作 ====================

  /**
   * 点赞帖子
   */
  async likePost(id: string): Promise<Post> {
    try {
      const response = await this.api.post<PostApiResponse>(`/posts/${id}/like`);
      const post = this.mapToPost(response);

      // 更新缓存
      this.saveToMemoryCache(post);
      await this.saveToLocalCache(post);

      return post;
    } catch (error) {
      this.handleError(error, '点赞帖子');
    }
  }

  /**
   * 取消点赞
   */
  async unlikePost(id: string): Promise<Post> {
    try {
      const response = await this.api.delete<PostApiResponse>(`/posts/${id}/like`);
      const post = this.mapToPost(response);

      // 更新缓存
      this.saveToMemoryCache(post);
      await this.saveToLocalCache(post);

      return post;
    } catch (error) {
      this.handleError(error, '取消点赞');
    }
  }

  /**
   * 收藏帖子
   */
  async favoritePost(id: string): Promise<Post> {
    try {
      const response = await this.api.post<PostApiResponse>(`/posts/${id}/favorite`);
      const post = this.mapToPost(response);

      // 更新缓存
      this.saveToMemoryCache(post);
      await this.saveToLocalCache(post);

      return post;
    } catch (error) {
      this.handleError(error, '收藏帖子');
    }
  }

  /**
   * 取消收藏
   */
  async unfavoritePost(id: string): Promise<Post> {
    try {
      const response = await this.api.delete<PostApiResponse>(`/posts/${id}/favorite`);
      const post = this.mapToPost(response);

      // 更新缓存
      this.saveToMemoryCache(post);
      await this.saveToLocalCache(post);

      return post;
    } catch (error) {
      this.handleError(error, '取消收藏');
    }
  }

  // ==================== 缓存管理 ====================

  /**
   * 清除所有缓存
   */
  async clearAllCache(): Promise<void> {
    this.memoryCache.clear();
    try {
      await this.localDb.initialize();
      await this.localDb.enqueueWrite(async () => {
        await this.localDb.run('DELETE FROM posts_cache');
      });
    } catch (error) {
      console.error('[PostRepository] 清除所有缓存失败:', error);
    }
  }

  /**
   * 使指定帖子的缓存失效
   */
  async invalidateCache(id: string): Promise<void> {
    this.memoryCache.delete(id);
    await this.clearLocalCache(id);
  }
}

// ==================== 单例导出 ====================

export const postRepository = new PostRepository(apiDataSource, localDataSource);
export default postRepository;
