import { contextBridge, ipcRenderer, webUtils } from 'electron' import { electronAPI } from '@electron-toolkit/preload' // Custom APIs for renderer const api = { deleteClass: (classId: string) => ipcRenderer.invoke('student:delete-class', classId), deleteStudentProfile: (profileId: string) => ipcRenderer.invoke('student:delete-profile', profileId), exportEmptyClassFolder: (payload: { className: string; classId: string; childNames: string[] }) => ipcRenderer.invoke('classes:export-empty-folder', payload), loadStudentData: (payload?: { includeProfiles?: boolean includeImages?: boolean includeClassImages?: boolean }) => ipcRenderer.invoke('student:load', payload), listStudentProfiles: (payload: { page: number pageSize: number query?: string classId?: string }) => ipcRenderer.invoke('student:list', payload), getStudentProfile: (profileId: string) => ipcRenderer.invoke('student:get-profile', profileId), updateStudentProfile: (profile: { id: string classId: string className: string name: string englishName: string gender: string birthday: string zodiac: string friends: string[] hobbies: string[] favoriteGames: string[] favoriteFoods: string[] traits: string comment: string commentGeneratedAt: string reportGenerated: boolean meImage: string workImage1: string workImage2: string importedAt: string }) => ipcRenderer.invoke('student:update-profile', profile), importStudentPhotos: (payload: { batchId: string; classId: string; zipPath: string }) => ipcRenderer.invoke('photos:import', payload), pausePhotoImport: (batchId: string) => ipcRenderer.invoke('photos:pause-import', batchId), resumePhotoImport: (batchId: string) => ipcRenderer.invoke('photos:resume-import', batchId), stopPhotoImport: (batchId: string) => ipcRenderer.invoke('photos:stop-import', batchId), onPhotoImportProgress: ( callback: (progress: { batchId: string status: 'parsing' | 'started' | 'image-finished' | 'paused' | 'stopped' | 'finished' classId: string className: string studentId?: string studentName?: string current: number total: number matchedImageCount: number skippedImageCount: number }) => void ): (() => void) => { const listener = ( _: Electron.IpcRendererEvent, progress: Parameters[0] ): void => callback(progress) ipcRenderer.on('photos:import-progress', listener) return () => ipcRenderer.removeListener('photos:import-progress', listener) }, generateStudentComment: (payload: { profileId: string }) => ipcRenderer.invoke('student:generate-comment', payload), generateStudentComments: (payload: { classId?: string; profileIds?: string[] }) => ipcRenderer.invoke('student:generate-comments', payload), addClassZodiacs: (payload: { classId: string }) => ipcRenderer.invoke('student:add-class-zodiacs', payload), pauseCommentGeneration: (batchId: string) => ipcRenderer.invoke('comments:pause-generation', batchId), resumeCommentGeneration: (batchId: string) => ipcRenderer.invoke('comments:resume-generation', batchId), stopCommentGeneration: (batchId: string) => ipcRenderer.invoke('comments:stop-generation', batchId), listModels: (payload: { baseUrl: string; apiKey: string }) => ipcRenderer.invoke('models:list', payload), testModelConnection: (modelConfig: { provider: string baseUrl: string apiKey: string model: string temperature: string maxTokens: string systemPrompt: string }) => ipcRenderer.invoke('models:test-connection', modelConfig), replaceClassProfiles: (payload: { classItem: { id: string name: string type: string teacherNames: string[] familyPhoto?: string } profiles: Array<{ id: string classId: string className: string name: string englishName: string gender: string birthday: string zodiac: string friends: string[] hobbies: string[] favoriteGames: string[] favoriteFoods: string[] traits: string comment?: string commentGeneratedAt?: string reportGenerated?: boolean meImage?: string workImage1?: string workImage2?: string importedAt: string }> }) => ipcRenderer.invoke('student:replace-class-profiles', payload), migrateLocalStudentData: (payload: { classes: Array<{ id: string name: string type: string teacherNames: string[] familyPhoto?: string }> profiles: Array<{ id: string classId: string className: string name: string englishName: string gender: string birthday: string zodiac: string friends: string[] hobbies: string[] favoriteGames: string[] favoriteFoods: string[] traits: string comment?: string commentGeneratedAt?: string reportGenerated?: boolean meImage?: string workImage1?: string workImage2?: string importedAt: string }> }) => ipcRenderer.invoke('student:migrate-local', payload), saveClasses: ( classes: Array<{ id: string name: string type: string teacherNames: string[] familyPhoto?: string }> ) => ipcRenderer.invoke('student:save-classes', classes), loadSettings: () => ipcRenderer.invoke('settings:load'), saveSettings: (modelConfig: { provider: string baseUrl: string apiKey: string model: string temperature: string maxTokens: string systemPrompt: string }) => ipcRenderer.invoke('settings:save', modelConfig), saveClassTypeConfigs: ( classTypeConfigs: Array<{ id: string label: string courseContent: string }> ) => ipcRenderer.invoke('settings:save-class-types', classTypeConfigs), loadTemplates: () => ipcRenderer.invoke('templates:load'), selectTemplateFile: () => ipcRenderer.invoke('templates:select-file'), parseTemplatePlaceholders: (filePath: string) => ipcRenderer.invoke('templates:parse-placeholders', filePath), getDroppedFilePath: (file: File) => webUtils.getPathForFile(file), saveTemplate: (template: { id?: string name: string grade: string semester: 'first' | 'second' type: 'portrait' | 'landscape' sourceFilePath: string }) => ipcRenderer.invoke('templates:save', template), openTemplate: (filePath: string) => ipcRenderer.invoke('templates:open', filePath), deleteTemplate: (id: string) => ipcRenderer.invoke('templates:delete', id), loadReports: () => ipcRenderer.invoke('reports:load'), generateReports: (payload: { templateId: string; classId: string; studentIds?: string[] }) => ipcRenderer.invoke('reports:generate', payload), pauseReportGeneration: (batchId: string) => ipcRenderer.invoke('reports:pause-generation', batchId), resumeReportGeneration: (batchId: string) => ipcRenderer.invoke('reports:resume-generation', batchId), stopReportGeneration: (batchId: string) => ipcRenderer.invoke('reports:stop-generation', batchId), openReport: (filePath: string) => ipcRenderer.invoke('reports:open', filePath), downloadReport: (id: string) => ipcRenderer.invoke('reports:download', id), downloadClassReports: (payload: { classId: string }) => ipcRenderer.invoke('reports:download-class', payload), onReportDownloadProgress: ( callback: (progress: { batchId: string status: 'started' | 'file-started' | 'file-finished' | 'finished' | 'failed' classId: string className: string reportId?: string reportTitle?: string current: number total: number filePath?: string error?: string }) => void ): (() => void) => { const listener = ( _: Electron.IpcRendererEvent, progress: Parameters[0] ): void => callback(progress) ipcRenderer.on('reports:download-class-progress', listener) return () => ipcRenderer.removeListener('reports:download-class-progress', listener) }, onReportGenerationProgress: ( callback: (progress: { batchId: string status: | 'started' | 'student-started' | 'student-finished' | 'student-failed' | 'paused' | 'stopped' | 'finished' classId: string className: string studentId?: string studentName?: string current: number total: number report?: unknown error?: string }) => void ): (() => void) => { const listener = ( _: Electron.IpcRendererEvent, progress: Parameters[0] ): void => callback(progress) ipcRenderer.on('reports:generation-progress', listener) return () => ipcRenderer.removeListener('reports:generation-progress', listener) }, onCommentGenerationProgress: ( callback: (progress: { batchId: string status: | 'started' | 'student-started' | 'student-finished' | 'student-failed' | 'paused' | 'stopped' | 'finished' classId?: string className?: string studentId?: string studentName?: string current: number total: number profile?: unknown error?: string }) => void ): (() => void) => { const listener = ( _: Electron.IpcRendererEvent, progress: Parameters[0] ): void => callback(progress) ipcRenderer.on('comments:generation-progress', listener) return () => ipcRenderer.removeListener('comments:generation-progress', listener) }, deleteReport: (id: string) => ipcRenderer.invoke('reports:delete', id), deleteAllReports: () => ipcRenderer.invoke('reports:delete-all') } // Use `contextBridge` APIs to expose Electron APIs to // renderer only if context isolation is enabled, otherwise // just add to the DOM global. if (process.contextIsolated) { try { contextBridge.exposeInMainWorld('electron', electronAPI) contextBridge.exposeInMainWorld('api', api) } catch (error) { console.error(error) } } else { // @ts-ignore (define in dts) window.electron = electronAPI // @ts-ignore (define in dts) window.api = api }