import {create} from 'zustand';
import {useShallow} from 'zustand/react/shallow';
import type {Message} from '@modules/chats/interfaces';

interface PinnedMessagesState {
  pinnedByChannel: Record<string, Message[]>;
  loadingByChannel: Record<string, boolean>;
  setPinned: (channel: string, items: Message[]) => void;
  setLoading: (channel: string, isLoading: boolean) => void;
  updateMessage: (channel: string, updated: Message) => void;
  clear: () => void;
}

const initialState = {
  pinnedByChannel: {} as Record<string, Message[]>,
  loadingByChannel: {} as Record<string, boolean>,
};

const emptyPinnedArray: Message[] = [];

export const usePinnedMessages = create<PinnedMessagesState>(set => ({
  ...initialState,

  setPinned: (channel, items) =>
    set(state => ({
      pinnedByChannel: {...state.pinnedByChannel, [channel]: items},
    })),

  setLoading: (channel, isLoading) =>
    set(state => ({
      loadingByChannel: {...state.loadingByChannel, [channel]: isLoading},
    })),

  updateMessage: (channel, updated) =>
    set(state => {
      const pinned = state.pinnedByChannel[channel];
      if (!pinned?.some(m => m.ts === updated.ts)) {
        return state;
      }
      return {
        pinnedByChannel: {
          ...state.pinnedByChannel,
          [channel]: pinned.map(m => (m.ts === updated.ts ? updated : m)),
        },
      };
    }),

  clear: () => set(initialState),
}));

export const getPinnedCountForChannel = (channel: string) =>
  (usePinnedMessages.getState().pinnedByChannel[channel] ?? emptyPinnedArray)
    .length;

export const usePinnedMessagesForChannel = (channel: string) =>
  usePinnedMessages(
    useShallow(state => ({
      pinned: state.pinnedByChannel[channel] ?? emptyPinnedArray,
      isLoading: state.loadingByChannel[channel] ?? false,
    })),
  );

export const useIsPinned = (channel: string, ts: string) =>
  usePinnedMessages(
    state => !!state.pinnedByChannel[channel]?.some(m => m.ts === ts),
  );
