import { create } from 'zustand';
import type { Post } from '../../core/entities/Post';

export interface PostsState {
  posts: Post[];
  isLoading: boolean;
  isRefreshing: boolean;
  hasMore: boolean;
  error: string | null;
  cursor: string | null;
  currentPage: number;
  lastLoadTime: number | null;
  lastParams?: any;
}

export interface PostDetailState {
  post: Post | null;
  isLoading: boolean;
  error: string | null;
}

export interface PostListStoreState {
  postsStateMap: Map<string, PostsState>;
  postDetailStateMap: Map<string, PostDetailState>;
}

export interface PostListStoreActions {
  getPostsState: (key: string) => PostsState;
  getPostDetailState: (postId: string) => PostDetailState;
  updatePostsState: (key: string, partial: Partial<PostsState>) => void;
  updatePostDetailState: (postId: string, partial: Partial<PostDetailState>) => void;
  updatePostInLists: (postId: string, updatedPost: Post) => void;
  removePostFromLists: (postId: string) => void;
  applyShareCountUpdate: (postId: string, sharesCount: number) => void;
  clearPostsState: (key: string) => void;
  clearPostDetailState: (postId: string) => void;
  clearAllStates: () => void;
  reset: () => void;
}

const DEFAULT_POSTS_STATE: PostsState = {
  posts: [],
  isLoading: false,
  isRefreshing: false,
  hasMore: true,
  error: null,
  cursor: null,
  currentPage: 1,
  lastLoadTime: null,
};

const DEFAULT_POST_DETAIL_STATE: PostDetailState = {
  post: null,
  isLoading: false,
  error: null,
};

export type PostListStore = PostListStoreState & PostListStoreActions;

export const usePostListStore = create<PostListStore>((set, get) => ({
  postsStateMap: new Map(),
  postDetailStateMap: new Map(),

  getPostsState: (key: string) => {
    return get().postsStateMap.get(key) ?? { ...DEFAULT_POSTS_STATE };
  },

  getPostDetailState: (postId: string) => {
    return get().postDetailStateMap.get(postId) ?? { ...DEFAULT_POST_DETAIL_STATE };
  },

  updatePostsState: (key: string, partial: Partial<PostsState>) => {
    set(state => {
      const current = state.postsStateMap.get(key) ?? { ...DEFAULT_POSTS_STATE };
      const newMap = new Map(state.postsStateMap);
      newMap.set(key, { ...current, ...partial });
      return { postsStateMap: newMap };
    });
  },

  updatePostDetailState: (postId: string, partial: Partial<PostDetailState>) => {
    set(state => {
      const current = state.postDetailStateMap.get(postId) ?? { ...DEFAULT_POST_DETAIL_STATE };
      const newMap = new Map(state.postDetailStateMap);
      newMap.set(postId, { ...current, ...partial });
      return { postDetailStateMap: newMap };
    });
  },

  updatePostInLists: (postId: string, updatedPost: Post) => {
    set(state => {
      const newMap = new Map(state.postsStateMap);
      let changed = false;
      for (const [key, postsState] of newMap) {
        const index = postsState.posts.findIndex(p => p.id === postId);
        if (index !== -1) {
          const newPosts = [...postsState.posts];
          newPosts[index] = updatedPost;
          newMap.set(key, { ...postsState, posts: newPosts });
          changed = true;
        }
      }
      return changed ? { postsStateMap: newMap } : state;
    });
  },

  removePostFromLists: (postId: string) => {
    set(state => {
      const newMap = new Map(state.postsStateMap);
      let changed = false;
      for (const [key, postsState] of newMap) {
        const filtered = postsState.posts.filter(p => p.id !== postId);
        if (filtered.length !== postsState.posts.length) {
          newMap.set(key, { ...postsState, posts: filtered });
          changed = true;
        }
      }
      return changed ? { postsStateMap: newMap } : state;
    });
  },

  applyShareCountUpdate: (postId: string, sharesCount: number) => {
    set(state => {
      const newPostsMap = new Map(state.postsStateMap);
      let postsChanged = false;
      for (const [key, postsState] of newPostsMap) {
        const index = postsState.posts.findIndex(p => p.id === postId);
        if (index !== -1) {
          const newPosts = [...postsState.posts];
          const cur = newPosts[index];
          newPosts[index] = { ...cur, sharesCount, shares_count: sharesCount };
          newPostsMap.set(key, { ...postsState, posts: newPosts });
          postsChanged = true;
        }
      }

      const newDetailMap = new Map(state.postDetailStateMap);
      let detailChanged = false;
      const detail = newDetailMap.get(postId);
      if (detail?.post) {
        newDetailMap.set(postId, {
          ...detail,
          post: { ...detail.post, sharesCount, shares_count: sharesCount },
        });
        detailChanged = true;
      }

      if (!postsChanged && !detailChanged) return state;
      return {
        ...(postsChanged ? { postsStateMap: newPostsMap } : {}),
        ...(detailChanged ? { postDetailStateMap: newDetailMap } : {}),
      };
    });
  },

  clearPostsState: (key: string) => {
    set(state => {
      const newMap = new Map(state.postsStateMap);
      newMap.delete(key);
      return { postsStateMap: newMap };
    });
  },

  clearPostDetailState: (postId: string) => {
    set(state => {
      const newMap = new Map(state.postDetailStateMap);
      newMap.delete(postId);
      return { postDetailStateMap: newMap };
    });
  },

  clearAllStates: () => {
    set({
      postsStateMap: new Map(),
      postDetailStateMap: new Map(),
    });
  },

  reset: () => {
    set({
      postsStateMap: new Map(),
      postDetailStateMap: new Map(),
    });
  },
}));
