import { create } from 'zustand';
import type { Snapshot, RollBroadcast, PrivateHandout } from '@/lib/sync/messages';
import type { Character } from '@/lib/schemas';

export type SeatStatus = 'none' | 'pending' | 'granted';
export interface RollEntry extends RollBroadcast { id: number }
export interface ChatEntry { id: number; from: string; body: string; scope: 'table' | 'whisper'; to?: string; mine?: boolean }

interface PlayerSessionState {
  snapshot: Snapshot | null;
  /** map image data URLs keyed by map id, cached so they don't re-stream */
  images: Record<string, string>;
  /** the seated player's authoritative character (granted by the GM) */
  myCharacter: Character | null;
  seatStatus: SeatStatus;
  /** recent dice-roll broadcasts from the whole table */
  rolls: RollEntry[];
  /** chat messages this client can see (table + whispers involving them) */
  chat: ChatEntry[];
  /** a handout/note the GM sent privately to this player only */
  privateHandout: PrivateHandout | null;
  setSnapshot: (s: Snapshot) => void;
  setImage: (id: string, dataUrl: string) => void;
  setMyCharacter: (c: Character) => void;
  patchMyCharacter: (diff: Partial<Character>) => void;
  setSeatStatus: (s: SeatStatus) => void;
  addRoll: (r: RollBroadcast) => void;
  addChat: (c: Omit<ChatEntry, 'id'>) => void;
  setPrivateHandout: (h: PrivateHandout | null) => void;
  reset: () => void;
}

let rollSeq = 0;

/** Ephemeral store holding what a joined player currently sees (never persisted). */
export const usePlayerSessionStore = create<PlayerSessionState>()((set) => ({
  snapshot: null,
  images: {},
  myCharacter: null,
  seatStatus: 'none',
  rolls: [],
  chat: [],
  privateHandout: null,
  setSnapshot: (snapshot) => set({ snapshot }),
  setImage: (id, dataUrl) => set((s) => ({ images: { ...s.images, [id]: dataUrl } })),
  setMyCharacter: (c) => set({ myCharacter: c, seatStatus: 'granted' }),
  patchMyCharacter: (diff) => set((s) => (s.myCharacter ? { myCharacter: { ...s.myCharacter, ...diff } } : {})),
  setSeatStatus: (seatStatus) => set({ seatStatus }),
  addRoll: (r) => set((s) => ({ rolls: [{ ...r, id: ++rollSeq }, ...s.rolls].slice(0, 30) })),
  addChat: (c) => set((s) => ({ chat: [...s.chat, { ...c, id: ++rollSeq }].slice(-200) })),
  setPrivateHandout: (privateHandout) => set({ privateHandout }),
  reset: () => set({ snapshot: null, images: {}, myCharacter: null, seatStatus: 'none', rolls: [], chat: [], privateHandout: null }),
}));
