import { create } from 'zustand';
import { api } from '../lib/api';

interface ReadStatesState {
  states: Record<string, string>; // channel_id -> last_read_message_id
  convStates: Record<string, string>; // conversation_id -> last_read_message_id
  loaded: boolean;
  fetchStates: () => Promise<void>;
  markRead: (channelId: string, messageId: string) => Promise<void>;
  markConvRead: (conversationId: string, messageId: string) => void;
  hasUnread: (channelId: string, latestMessageId?: string) => boolean;
  hasConvUnread: (conversationId: string, latestMessageId?: string) => boolean;
}

export const useReadStatesStore = create<ReadStatesState>()((set, get) => ({
  states: {},
  convStates: {},
  loaded: false,

  fetchStates: async () => {
    try {
      const states = await api.get<Record<string, string>>('/users/me/read-states');
      set({ states, loaded: true });
    } catch {
      set({ loaded: true });
    }
  },

  markRead: async (channelId: string, messageId: string) => {
    set((state) => ({
      states: { ...state.states, [channelId]: messageId },
    }));
    try {
      await api.put(`/channels/${channelId}/read`, { last_read_message_id: messageId });
    } catch {
      // optimistic update, ignore failure
    }
  },

  markConvRead: (conversationId: string, messageId: string) => {
    set((state) => ({
      convStates: { ...state.convStates, [conversationId]: messageId },
    }));
  },

  hasUnread: (channelId: string, latestMessageId?: string): boolean => {
    const state = get().states;
    const lastRead = state[channelId];
    // never viewed: unread if there are messages
    if (!lastRead) return !!latestMessageId;
    // viewed but newer messages exist
    if (latestMessageId && lastRead !== latestMessageId) return true;
    return false;
  },

  hasConvUnread: (conversationId: string, latestMessageId?: string): boolean => {
    const state = get().convStates;
    const lastRead = state[conversationId];
    if (!lastRead) return !!latestMessageId;
    if (latestMessageId && lastRead !== latestMessageId) return true;
    return false;
  },
}));
