import type { ChatSession, Message, Contact, ContactInfo } from './models' export interface ElectronAPI { window: { minimize: () => void maximize: () => void close: () => void openAgreementWindow: () => Promise completeOnboarding: () => Promise openOnboardingWindow: () => Promise setTitleBarOverlay: (options: { symbolColor: string }) => void openVideoPlayerWindow: (videoPath: string, videoWidth?: number, videoHeight?: number) => Promise resizeToFitVideo: (videoWidth: number, videoHeight: number) => Promise openImageViewerWindow: (imagePath: string) => Promise openChatHistoryWindow: (sessionId: string, messageId: number) => Promise } config: { get: (key: string) => Promise set: (key: string, value: unknown) => Promise clear: () => Promise } dialog: { openFile: (options?: Electron.OpenDialogOptions) => Promise openDirectory: (options?: Electron.OpenDialogOptions) => Promise saveFile: (options?: Electron.SaveDialogOptions) => Promise } shell: { openPath: (path: string) => Promise openExternal: (url: string) => Promise } app: { getDownloadsPath: () => Promise getVersion: () => Promise checkForUpdates: () => Promise<{ hasUpdate: boolean; version?: string; releaseNotes?: string }> downloadAndInstall: () => Promise ignoreUpdate: (version: string) => Promise<{ success: boolean }> onDownloadProgress: (callback: (progress: number) => void) => () => void onUpdateAvailable: (callback: (info: { version: string; releaseNotes: string }) => void) => () => void } log: { getPath: () => Promise read: () => Promise<{ success: boolean; content?: string; error?: string }> } dbPath: { autoDetect: () => Promise<{ success: boolean; path?: string; error?: string }> scanWxids: (rootPath: string) => Promise scanWxidCandidates: (rootPath: string) => Promise getDefault: () => Promise } wcdb: { testConnection: (dbPath: string, hexKey: string, wxid: string) => Promise<{ success: boolean; error?: string; sessionCount?: number }> open: (dbPath: string, hexKey: string, wxid: string) => Promise close: () => Promise } key: { autoGetDbKey: () => Promise<{ success: boolean; key?: string; error?: string; logs?: string[] }> autoGetImageKey: (manualDir?: string) => Promise<{ success: boolean; xorKey?: number; aesKey?: string; error?: string }> onDbKeyStatus: (callback: (payload: { message: string; level: number }) => void) => () => void onImageKeyStatus: (callback: (payload: { message: string }) => void) => () => void } chat: { connect: () => Promise<{ success: boolean; error?: string }> getSessions: () => Promise<{ success: boolean; sessions?: ChatSession[]; error?: string }> enrichSessionsContactInfo: (usernames: string[]) => Promise<{ success: boolean contacts?: Record error?: string }> getMessages: (sessionId: string, offset?: number, limit?: number, startTime?: number, endTime?: number, ascending?: boolean) => Promise<{ success: boolean; messages?: Message[]; hasMore?: boolean; error?: string }> getLatestMessages: (sessionId: string, limit?: number) => Promise<{ success: boolean messages?: Message[] error?: string }> getNewMessages: (sessionId: string, minTime: number, limit?: number) => Promise<{ success: boolean messages?: Message[] error?: string }> getContact: (username: string) => Promise getContactAvatar: (username: string) => Promise<{ avatarUrl?: string; displayName?: string } | null> resolveTransferDisplayNames: (chatroomId: string, payerUsername: string, receiverUsername: string) => Promise<{ payerName: string; receiverName: string }> getContacts: () => Promise<{ success: boolean contacts?: ContactInfo[] error?: string }> getMyAvatarUrl: () => Promise<{ success: boolean; avatarUrl?: string; error?: string }> downloadEmoji: (cdnUrl: string, md5?: string) => Promise<{ success: boolean; localPath?: string; error?: string }> close: () => Promise getSessionDetail: (sessionId: string) => Promise<{ success: boolean detail?: { wxid: string displayName: string remark?: string nickName?: string alias?: string avatarUrl?: string messageCount: number firstMessageTime?: number latestMessageTime?: number messageTables: { dbName: string; tableName: string; count: number }[] } error?: string }> getImageData: (sessionId: string, msgId: string) => Promise<{ success: boolean; data?: string; error?: string }> getVoiceData: (sessionId: string, msgId: string, createTime?: number, serverId?: string | number) => Promise<{ success: boolean; data?: string; error?: string }> getAllVoiceMessages: (sessionId: string) => Promise<{ success: boolean; messages?: Message[]; error?: string }> resolveVoiceCache: (sessionId: string, msgId: string) => Promise<{ success: boolean; hasCache: boolean; data?: string }> getVoiceTranscript: (sessionId: string, msgId: string, createTime?: number) => Promise<{ success: boolean; transcript?: string; error?: string }> onVoiceTranscriptPartial: (callback: (payload: { msgId: string; text: string }) => void) => () => void execQuery: (kind: string, path: string | null, sql: string) => Promise<{ success: boolean; rows?: any[]; error?: string }> getMessage: (sessionId: string, localId: number) => Promise<{ success: boolean; message?: Message; error?: string }> onWcdbChange: (callback: (event: any, data: { type: string; json: string }) => void) => () => void } image: { decrypt: (payload: { sessionId?: string; imageMd5?: string; imageDatName?: string; force?: boolean }) => Promise<{ success: boolean; localPath?: string; error?: string }> resolveCache: (payload: { sessionId?: string; imageMd5?: string; imageDatName?: string }) => Promise<{ success: boolean; localPath?: string; hasUpdate?: boolean; error?: string }> preload: (payloads: Array<{ sessionId?: string; imageMd5?: string; imageDatName?: string }>) => Promise onUpdateAvailable: (callback: (payload: { cacheKey: string; imageMd5?: string; imageDatName?: string }) => void) => () => void onCacheResolved: (callback: (payload: { cacheKey: string; imageMd5?: string; imageDatName?: string; localPath: string }) => void) => () => void } video: { getVideoInfo: (videoMd5: string) => Promise<{ success: boolean exists: boolean videoUrl?: string coverUrl?: string thumbUrl?: string error?: string }> parseVideoMd5: (content: string) => Promise<{ success: boolean md5?: string error?: string }> } analytics: { getOverallStatistics: (force?: boolean) => Promise<{ success: boolean data?: { totalMessages: number textMessages: number imageMessages: number voiceMessages: number videoMessages: number emojiMessages: number otherMessages: number sentMessages: number receivedMessages: number firstMessageTime: number | null lastMessageTime: number | null activeDays: number messageTypeCounts: Record } error?: string }> getContactRankings: (limit?: number, beginTimestamp?: number, endTimestamp?: number) => Promise<{ success: boolean data?: Array<{ username: string displayName: string avatarUrl?: string wechatId?: string messageCount: number sentCount: number receivedCount: number lastMessageTime: number | null }> error?: string }> getTimeDistribution: () => Promise<{ success: boolean data?: { hourlyDistribution: Record weekdayDistribution: Record monthlyDistribution: Record } error?: string }> getExcludedUsernames: () => Promise<{ success: boolean data?: string[] error?: string }> setExcludedUsernames: (usernames: string[]) => Promise<{ success: boolean data?: string[] error?: string }> getExcludeCandidates: () => Promise<{ success: boolean data?: Array<{ username: string displayName: string avatarUrl?: string wechatId?: string }> error?: string }> onProgress: (callback: (payload: { status: string; progress: number }) => void) => () => void } cache: { clearAnalytics: () => Promise<{ success: boolean; error?: string }> clearImages: () => Promise<{ success: boolean; error?: string }> clearAll: () => Promise<{ success: boolean; error?: string }> } groupAnalytics: { getGroupChats: () => Promise<{ success: boolean data?: Array<{ username: string displayName: string memberCount: number avatarUrl?: string }> error?: string }> getGroupMembers: (chatroomId: string) => Promise<{ success: boolean data?: Array<{ username: string displayName: string avatarUrl?: string nickname?: string alias?: string remark?: string groupNickname?: string }> error?: string }> getGroupMessageRanking: (chatroomId: string, limit?: number, startTime?: number, endTime?: number) => Promise<{ success: boolean data?: Array<{ member: { username: string displayName: string avatarUrl?: string } messageCount: number }> error?: string }> getGroupActiveHours: (chatroomId: string, startTime?: number, endTime?: number) => Promise<{ success: boolean data?: { hourlyDistribution: Record } error?: string }> getGroupMediaStats: (chatroomId: string, startTime?: number, endTime?: number) => Promise<{ success: boolean data?: { typeCounts: Array<{ type: number name: string count: number }> total: number } error?: string }> exportGroupMembers: (chatroomId: string, outputPath: string) => Promise<{ success: boolean count?: number error?: string }> } annualReport: { getAvailableYears: () => Promise<{ success: boolean data?: number[] error?: string }> generateReport: (year: number) => Promise<{ success: boolean data?: { year: number totalMessages: number totalFriends: number coreFriends: Array<{ username: string displayName: string avatarUrl?: string messageCount: number sentCount: number receivedCount: number }> monthlyTopFriends: Array<{ month: number displayName: string avatarUrl?: string messageCount: number }> peakDay: { date: string messageCount: number topFriend?: string topFriendCount?: number } | null longestStreak: { friendName: string days: number startDate: string endDate: string } | null activityHeatmap: { data: number[][] } midnightKing: { displayName: string count: number percentage: number } | null selfAvatarUrl?: string mutualFriend: { displayName: string avatarUrl?: string sentCount: number receivedCount: number ratio: number } | null socialInitiative: { initiatedChats: number receivedChats: number initiativeRate: number } | null responseSpeed: { avgResponseTime: number fastestFriend: string fastestTime: number } | null topPhrases: Array<{ phrase: string count: number }> } error?: string }> exportImages: (payload: { baseDir: string; folderName: string; images: Array<{ name: string; dataUrl: string }> }) => Promise<{ success: boolean dir?: string error?: string }> onProgress: (callback: (payload: { status: string; progress: number }) => void) => () => void } dualReport: { generateReport: (payload: { friendUsername: string; year: number }) => Promise<{ success: boolean data?: { year: number selfName: string selfAvatarUrl?: string friendUsername: string friendName: string friendAvatarUrl?: string firstChat: { createTime: number createTimeStr: string content: string isSentByMe: boolean senderUsername?: string } | null firstChatMessages?: Array<{ content: string isSentByMe: boolean createTime: number createTimeStr: string }> yearFirstChat?: { createTime: number createTimeStr: string content: string isSentByMe: boolean friendName: string firstThreeMessages: Array<{ content: string isSentByMe: boolean createTime: number createTimeStr: string }> } | null stats: { totalMessages: number totalWords: number imageCount: number voiceCount: number emojiCount: number myTopEmojiMd5?: string friendTopEmojiMd5?: string myTopEmojiUrl?: string topPhrases: Array<{ phrase: string; count: number }> myExclusivePhrases: Array<{ phrase: string; count: number }> friendExclusivePhrases: Array<{ phrase: string; count: number }> heatmap?: number[][] initiative?: { initiated: number; received: number } response?: { avg: number; fastest: number; count: number } monthly?: Record streak?: { days: number; startDate: string; endDate: string } } } error?: string }> onProgress: (callback: (payload: { status: string; progress: number }) => void) => () => void } export: { getExportStats: (sessionIds: string[], options: any) => Promise<{ totalMessages: number voiceMessages: number cachedVoiceCount: number needTranscribeCount: number mediaMessages: number estimatedSeconds: number sessions: Array<{ sessionId: string; displayName: string; totalCount: number; voiceCount: number }> }> exportSessions: (sessionIds: string[], outputDir: string, options: ExportOptions) => Promise<{ success: boolean successCount?: number failCount?: number error?: string }> exportSession: (sessionId: string, outputPath: string, options: ExportOptions) => Promise<{ success: boolean error?: string }> exportContacts: (outputDir: string, options: { format: 'json' | 'csv' | 'vcf'; exportAvatars: boolean; contactTypes: { friends: boolean; groups: boolean; officials: boolean } }) => Promise<{ success: boolean successCount?: number error?: string }> onProgress: (callback: (payload: ExportProgress) => void) => () => void } whisper: { downloadModel: () => Promise<{ success: boolean; modelPath?: string; tokensPath?: string; error?: string }> getModelStatus: () => Promise<{ success: boolean; exists?: boolean; modelPath?: string; tokensPath?: string; sizeBytes?: number; error?: string }> onDownloadProgress: (callback: (payload: { modelName: string; downloadedBytes: number; totalBytes?: number; percent?: number }) => void) => () => void } sns: { getTimeline: (limit: number, offset: number, usernames?: string[], keyword?: string, startTime?: number, endTime?: number) => Promise<{ success: boolean timeline?: Array<{ id: string username: string nickname: string avatarUrl?: string createTime: number contentDesc: string type?: number media: Array<{ url: string thumb: string md5?: string token?: string key?: string encIdx?: string livePhoto?: { url: string thumb: string md5?: string token?: string key?: string encIdx?: string } }> likes: Array comments: Array<{ id: string; nickname: string; content: string; refCommentId: string; refNickname?: string }> rawXml?: string }> error?: string }> debugResource: (url: string) => Promise<{ success: boolean; status?: number; headers?: any; error?: string }> proxyImage: (url: string) => Promise<{ success: boolean; dataUrl?: string; error?: string }> } llama: { loadModel: (modelPath: string) => Promise createSession: (systemPrompt?: string) => Promise chat: (message: string) => Promise<{ success: boolean; response?: any; error?: string }> downloadModel: (url: string, savePath: string) => Promise getModelsPath: () => Promise checkFileExists: (filePath: string) => Promise getModelStatus: (modelPath: string) => Promise<{ exists: boolean; path?: string; size?: number; error?: string }> onToken: (callback: (token: string) => void) => () => void onDownloadProgress: (callback: (payload: { downloaded: number; total: number; speed: number }) => void) => () => void } } export interface ExportOptions { format: 'chatlab' | 'chatlab-jsonl' | 'json' | 'html' | 'txt' | 'excel' | 'sql' dateRange?: { start: number; end: number } | null exportMedia?: boolean exportAvatars?: boolean exportImages?: boolean exportVoices?: boolean exportEmojis?: boolean exportVoiceAsText?: boolean excelCompactColumns?: boolean txtColumns?: string[] sessionLayout?: 'shared' | 'per-session' displayNamePreference?: 'group-nickname' | 'remark' | 'nickname' exportConcurrency?: number } export interface ExportProgress { current: number total: number currentSession: string phase: 'preparing' | 'exporting' | 'exporting-media' | 'exporting-voice' | 'writing' | 'complete' phaseProgress?: number phaseTotal?: number phaseLabel?: string } export interface WxidInfo { wxid: string modifiedTime: number } declare global { interface Window { electronAPI: ElectronAPI } // Electron 类型声明 namespace Electron { interface OpenDialogOptions { title?: string defaultPath?: string filters?: { name: string; extensions: string[] }[] properties?: ('openFile' | 'openDirectory' | 'multiSelections' | 'createDirectory')[] } interface OpenDialogReturnValue { canceled: boolean filePaths: string[] } interface SaveDialogOptions { title?: string defaultPath?: string filters?: { name: string; extensions: string[] }[] } interface SaveDialogReturnValue { canceled: boolean filePath?: string } } } export { }