/**
 * Stores shim index.
 *
 * The new UI uses MobX stores. This project uses Convex + React Contexts.
 * Each store here is a plain object with getter methods returning sane
 * defaults. Components rewired to Convex will stop reading these stubs.
 */

import type {
	Channel,
	Server,
	Member,
	Message,
	Role,
	PresenceStatus,
	VoiceParticipantSnapshot,
	CustomEmoji,
	EmojiPack,
	SavedMediaItem,
	SavedMediaKind,
} from '../matrix-client';

// ─── Helper: reactive-compatible getter wrappers ──────────────────────────
// The original stores used MobX `makeAutoObservable`. Components call these
// getters inside `observer()` wrappers. Our shims just return plain values,
// and we remove `observer` via the mobx-react-lite shim.

const ok = <T>(v: T): T => v;

// ─── AuthenticationStore ─────────────────────────────────────────────────
// isAuthenticated is a getter so the latest sessionStorage state is read
// every access. Keeps the new AppLayout redirect logic in sync with the
// existing session-restore flow in App.tsx (which sets sessionStorage).
export const AuthenticationStore = {
	get isAuthenticated(): boolean {
		if (typeof sessionStorage === 'undefined') return false;
		return !!(sessionStorage.getItem('privateKey') && sessionStorage.getItem('signingKey'));
	},
	get userId(): string {
		return typeof localStorage !== 'undefined' ? localStorage.getItem('userId') || '' : '';
	},
	get username(): string {
		return typeof localStorage !== 'undefined' ? localStorage.getItem('username') || '' : '';
	},
	isLoading: false,
	login: async (_username: string, _password: string) => {},
	register: async (_username: string, _password: string) => {},
	logout: async () => {},
	getUserId: () => (typeof localStorage !== 'undefined' ? localStorage.getItem('userId') || '' : ''),
	getUsername: () => (typeof localStorage !== 'undefined' ? localStorage.getItem('username') || '' : ''),
	async restoreSession(): Promise<boolean> {
		if (typeof sessionStorage === 'undefined') return false;
		return !!(sessionStorage.getItem('privateKey') && sessionStorage.getItem('signingKey'));
	},
};

// ─── ChannelStore ────────────────────────────────────────────────────────
export const ChannelStore = {
	getChannel: (_id: string): Channel | null => null,
	getChannels: (_serverId: string): Channel[] => [],
	listChannels: (_serverId: string): Channel[] => [],
	getCategories: (_serverId: string): Channel[] => [],
	getChannelsInCategory: (_serverId: string, _categoryId: string | null): Channel[] => [],
	setChannel: (_c: Channel) => {},
	removeChannel: (_id: string) => {},
};

// ─── ServerStore ─────────────────────────────────────────────────────────
export const ServerStore = {
	getServers: (): Server[] => [],
	getServer: (_id: string): Server | null => null,
	setServer: (_s: Server) => {},
	removeServer: (_id: string) => {},
};

// ─── MessageStore ────────────────────────────────────────────────────────
export const MessageStore = {
	getMessages: (_channelId: string): Message[] => [],
	getMessage: (_channelId: string, _id: string): Message | null => null,
	addMessage: (_m: Message) => {},
	updateMessage: (_channelId: string, _id: string, _patch: Partial<Message>) => {},
	removeMessage: (_channelId: string, _id: string) => {},
	getLastReadId: (_channelId: string): string | null => null,
};

// ─── UserStore ───────────────────────────────────────────────────────────
export const UserStore = {
	getUser: (_id: string): Member | null => null,
	getMe: (): Member | null => null,
	getDisplayName: (_id: string): string => '',
	getAvatarUrl: (_id: string): string | null => null,
	getPresence: (_id: string): PresenceStatus => 'offline',
	getAccentColor: (_id: string): string | null => null,
	setStatus: async (_status: PresenceStatus) => {},
	updateProfile: async (_patch: unknown) => {},
};

// ─── SelectionStore ──────────────────────────────────────────────────────
export const SelectionStore = {
	selectedServerId: null as string | null,
	selectedChannelId: null as string | null,
	isMobileViewport: typeof window !== 'undefined' ? window.innerWidth <= 768 : false,
	selectServer: (_id: string | null) => {},
	selectChannel: (_id: string | null) => {},
	syncFromPath: (_path: string) => {},
};

// ─── VoiceStore ──────────────────────────────────────────────────────────
export const VoiceStore = {
	connectedChannelId: null as string | null,
	isMuted: false,
	isDeafened: false,
	isCameraOn: false,
	isScreenSharing: false,
	connectionState: 'disconnected' as const,
	participants: [] as VoiceParticipantSnapshot[],
	getParticipants: (_channelId: string): VoiceParticipantSnapshot[] => [],
	toggleMute: () => {},
	toggleDeafen: () => {},
	toggleCamera: () => {},
	toggleScreenShare: () => {},
	disconnect: async () => {},
};

// ─── VoiceSettingsStore ──────────────────────────────────────────────────
export const VoiceSettingsStore = {
	inputDeviceId: 'default',
	outputDeviceId: 'default',
	inputVolume: 100,
	outputVolume: 100,
	noiseSuppression: true,
	echoCancellation: true,
	autoGainControl: true,
	setInputDevice: (_id: string) => {},
	setOutputDevice: (_id: string) => {},
};

// ─── RoleStore ───────────────────────────────────────────────────────────
export const RoleStore = {
	listRoles: (_serverId: string): Role[] => [],
	getRole: (_serverId: string, _id: string): Role | null => null,
	getMemberRoles: (_serverId: string, _userId: string): Role[] => [],
	getHighestHoistedRole: (_serverId: string, _userId: string): Role | null => null,
};

// ─── ReadStateStore ──────────────────────────────────────────────────────
export const ReadStateStore = {
	isUnread: (_channelId: string): boolean => false,
	getUnreadCount: (_channelId: string): number => 0,
	getMentionCount: (_channelId: string): number => 0,
	getLastReadId: (_channelId: string): string | null => null,
	markRead: async (_channelId: string) => {},
};

// ─── TypingStore ─────────────────────────────────────────────────────────
export const TypingStore = {
	getTypingUsers: (_channelId: string): Member[] => [],
	startTyping: async (_channelId: string) => {},
};

// ─── FriendStore ─────────────────────────────────────────────────────────
export const FriendStore = {
	getFriendChannels: (): Channel[] => [],
	getPendingChannels: (): Channel[] => [],
	getFriends: (): Member[] => [],
	getPending: (): Member[] => [],
	getIgnored: (): Member[] => [],
	isFriend: (_id: string): boolean => false,
	isPending: (_id: string): boolean => false,
	isIgnored: (_id: string): boolean => false,
};

// ─── PinStore ────────────────────────────────────────────────────────────
export const PinStore = {
	getPinned: (_channelId: string): Message[] => [],
	isPinned: (_channelId: string, _messageId: string): boolean => false,
};

// ─── SavedMediaStore ─────────────────────────────────────────────────────
export const SavedMediaStore = {
	list: (_kind?: SavedMediaKind): SavedMediaItem[] => [],
	isSaved: (_url: string): boolean => false,
	add: async (_item: SavedMediaItem) => {},
	remove: async (_id: string) => {},
};

// ─── EmojiPackStore ──────────────────────────────────────────────────────
export const EmojiPackStore = {
	listPacks: (): EmojiPack[] => [],
	getPack: (_id: string): EmojiPack | null => null,
	getEmoji: (_id: string): CustomEmoji | null => null,
	findByShortcode: (_shortcode: string): CustomEmoji | null => null,
};

// ─── PendingAttachmentStore ──────────────────────────────────────────────
export interface PendingAttachment {
	id: string;
	channelId: string;
	file: File;
	name: string;
	size: number;
	mimeType: string;
	previewUrl?: string;
	progress?: number;
	error?: string | null;
	spoiler?: boolean;
	description?: string;
	width?: number;
	height?: number;
}

export const PendingAttachmentStore = {
	getAttachments: (_channelId: string): PendingAttachment[] => [],
	addAttachment: (_a: PendingAttachment) => {},
	removeAttachment: (_channelId: string, _id: string) => {},
	updateAttachment: (_channelId: string, _id: string, _patch: Partial<PendingAttachment>) => {},
	clearAttachments: (_channelId: string) => {},
};

// ─── PersonalNotesStore ──────────────────────────────────────────────────
export const PersonalNotesStore = {
	getRoomId: (): string | null => null,
	isPersonalNotesRoom: (_id: string): boolean => false,
};

// ─── KeybindStore ────────────────────────────────────────────────────────
export const KeybindStore = {
	getCombo: (_action: string): string => '',
	getBinding: (_action: string): string => '',
	setCombo: (_action: string, _combo: string) => {},
	listActions: (): string[] => [],
};

// ─── SearchStore ─────────────────────────────────────────────────────────
export const SearchStore = {
	isOpen: false,
	query: '',
	results: [] as Message[],
	setQuery: (_q: string) => {},
	search: async (_q: string) => {},
	close: () => {},
};

// ─── CryptoStore ─────────────────────────────────────────────────────────
export const CryptoStore = {
	isReady: true,
	isSetup: true,
	needsSetup: false,
};

// ─── MatrixConnectionStore ───────────────────────────────────────────────
export const MatrixConnectionStore = {
	isReady: true,
	isConnecting: false,
	isConnected: true,
	error: null as string | null,
};

// ─── ThemeStore ──────────────────────────────────────────────────────────
export const ThemeStore = {
	theme: 'dark' as 'light' | 'dark',
	setTheme: (_t: 'light' | 'dark') => {},
};

// Default exports so `import Foo from '@app/stores/Foo'` also works
export default {
	AuthenticationStore,
	ChannelStore,
	ServerStore,
	MessageStore,
	UserStore,
	SelectionStore,
	VoiceStore,
	VoiceSettingsStore,
	RoleStore,
	ReadStateStore,
	TypingStore,
	FriendStore,
	PinStore,
	SavedMediaStore,
	EmojiPackStore,
	PendingAttachmentStore,
	PersonalNotesStore,
	KeybindStore,
	SearchStore,
	CryptoStore,
	MatrixConnectionStore,
	ThemeStore,
};

// Workaround for `ok` not being used (keeps TS from erroring on strict mode)
export { ok };
