import { ipcMain } from 'electron'

import {
  deleteClassWithProfiles,
  deleteStudentProfile,
  generateStudentComment,
  listStudentProfiles,
  loadStudentData,
  migrateLocalStudentData,
  replaceProfilesForClass,
  saveClasses,
  updateStudentProfile
} from '../services/studentService'
import type {
  ClassProfile,
  ChildProfile,
  DeleteClassResponse,
  DeleteStudentProfileResponse,
  GenerateStudentCommentInput,
  GenerateStudentCommentResponse,
  ListStudentProfilesInput,
  ListStudentProfilesResponse,
  LoadStudentDataResponse,
  ReplaceClassProfilesResponse,
  SaveClassesResponse,
  UpdateStudentProfileInput,
  UpdateStudentProfileResponse
} from '../types/student'

function getErrorMessage(error: unknown): string {
  return error instanceof Error ? error.message : '数据库操作失败'
}

export function registerStudentIpc(): void {
  ipcMain.handle('student:load', async (): Promise<LoadStudentDataResponse> => {
    try {
      const studentData = await loadStudentData()
      return {
        ok: true,
        ...studentData
      }
    } catch (error) {
      return {
        ok: false,
        message: getErrorMessage(error)
      }
    }
  })

  ipcMain.handle(
    'student:list',
    async (_, payload: ListStudentProfilesInput): Promise<ListStudentProfilesResponse> => {
      try {
        return {
          ok: true,
          ...(await listStudentProfiles(payload))
        }
      } catch (error) {
        return {
          ok: false,
          message: getErrorMessage(error)
        }
      }
    }
  )

  ipcMain.handle(
    'student:update-profile',
    async (_, payload: UpdateStudentProfileInput): Promise<UpdateStudentProfileResponse> => {
      try {
        return {
          ok: true,
          profile: await updateStudentProfile(payload)
        }
      } catch (error) {
        return {
          ok: false,
          message: getErrorMessage(error)
        }
      }
    }
  )

  ipcMain.handle(
    'student:generate-comment',
    async (_, payload: GenerateStudentCommentInput): Promise<GenerateStudentCommentResponse> => {
      try {
        return {
          ok: true,
          profile: await generateStudentComment(payload.profileId)
        }
      } catch (error) {
        return {
          ok: false,
          message: getErrorMessage(error)
        }
      }
    }
  )

  ipcMain.handle(
    'student:save-classes',
    async (_, classes: ClassProfile[]): Promise<SaveClassesResponse> => {
      try {
        await saveClasses(classes)
        return {
          ok: true
        }
      } catch (error) {
        return {
          ok: false,
          message: getErrorMessage(error)
        }
      }
    }
  )

  ipcMain.handle(
    'student:replace-class-profiles',
    async (
      _,
      payload: { classItem: ClassProfile; profiles: ChildProfile[] }
    ): Promise<ReplaceClassProfilesResponse> => {
      try {
        await replaceProfilesForClass(payload.classItem, payload.profiles)
        return {
          ok: true
        }
      } catch (error) {
        return {
          ok: false,
          message: getErrorMessage(error)
        }
      }
    }
  )

  ipcMain.handle(
    'student:delete-class',
    async (_, classId: string): Promise<DeleteClassResponse> => {
      try {
        await deleteClassWithProfiles(classId)
        return {
          ok: true
        }
      } catch (error) {
        return {
          ok: false,
          message: getErrorMessage(error)
        }
      }
    }
  )

  ipcMain.handle(
    'student:delete-profile',
    async (_, profileId: string): Promise<DeleteStudentProfileResponse> => {
      try {
        await deleteStudentProfile(profileId)
        return {
          ok: true
        }
      } catch (error) {
        return {
          ok: false,
          message: getErrorMessage(error)
        }
      }
    }
  )

  ipcMain.handle(
    'student:migrate-local',
    async (
      _,
      payload: { classes: ClassProfile[]; profiles: ChildProfile[] }
    ): Promise<SaveClassesResponse> => {
      try {
        await migrateLocalStudentData(payload.classes, payload.profiles)
        return {
          ok: true
        }
      } catch (error) {
        return {
          ok: false,
          message: getErrorMessage(error)
        }
      }
    }
  )
}
