'use server'

import { prisma } from '@/lib/prisma'
import { AccountInfo } from './types'

export async function updateUser(userId : string, updateData : AccountInfo) {
  console.log("updateData8888")
  console.log(updateData)
  const {
    firstName,
    lastName,
    username,
    phone,
    state,
    city,
    zipCode,
    rate,
    countryOfResidence,
    occupation,
    dateOfBirth,
    photoUrl,
    biography,
    linkedInURL,
    instagramURL,
    youtubeURL,
    spotifyURL,
    tiktokURL,
    twitterURL,
    amazonURL,
    websiteURL1,
    websiteURL2,
    languagesSpoken, 
    experiences,
    educations,
    videos,
    expertises, 
    photo,
    imageName,
    photoName,
    role
  } = updateData;

  try {
    // console.log({ updateData })

    // Start a transaction to perform multiple operations atomically
    const result = await prisma.$transaction(async (prisma) => {
      // Fetch existing experiences and educations for comparison
      const [
        existingExperiences,
        existingEducations,
        existingExpertises,
        existingLanguagesSpoken,
      ] = await Promise.all([
        prisma.experience.findMany({ where: { userId } }),
        prisma.education.findMany({ where: { userId } }),
        prisma.expertise.findMany({ where: { userId } }),
        prisma.language.findMany({ where: { userId } }),
      ])

      // Identify IDs of submitted experiences and educations
      const submittedExperienceIds = experiences?.map((e) => e.id)
        .filter((id) => id)

      const submittedEducationIds = educations?.map((e) => e.id)
        .filter((id) => id)

      const submittedExpertisesIds = educations?.map((e) => e.id)
        .filter((id) => id)

      const submittedlanguagesSpokenIds = languagesSpoken?.map((e) => e.id)
        .filter((id) => id)

      // Determine which existing items are not present in the submission
      const experiencesToDelete = existingExperiences.filter(
        (e) => !submittedExperienceIds?.includes(e.id)
      )
      const educationsToDelete = existingEducations.filter(
        (e) => !submittedEducationIds?.includes(e.id)
      )

      const expertisesToDelete = existingExpertises.filter(
        (e) => !submittedExpertisesIds?.includes(e.id)
      )

      const languagesSpokenToDelete = existingLanguagesSpoken.filter(
        (e) => !submittedlanguagesSpokenIds?.includes(e.id)
      )

      // Delete operations for items not present in the new submission
      const deleteExperiencesPromises = experiencesToDelete.map((experience) =>
        prisma.experience.delete({ where: { id: experience.id } })
      )
      const deleteEducationsPromises = educationsToDelete.map((education) =>
        prisma.education.delete({ where: { id: education.id } })
      )

      const deleteExpertisesPromises = expertisesToDelete.map((expertise) =>
        prisma.expertise.delete({ where: { id: expertise.id } })
      )

      const deletelanguagesPromises = languagesSpokenToDelete.map((language) =>
        prisma.language.delete({ where: { id: language.id } })
      )

      // Include these delete operations in your Promise.all along with create/update operations
      await Promise.all([
        // Other update/create operations...
        ...deleteExperiencesPromises,
        ...deleteEducationsPromises,
        ...deletelanguagesPromises,
        ...deleteExpertisesPromises,
      ])

      // Update the user's basic information
      const userUpdatePromise = prisma.user.update({
        where: { id: userId },
        data: {
          firstName,
          lastName,
          userName: username,
          phone : phone as string,
          countryOfResidence,
          state,
          city,
          rate,
          zipcode: zipCode,
          role: occupation,
          dateOfBirth,
          imageUrl: photoUrl,
          imageName: imageName,
          biography,
          linkedInURL,
          instagramURL,
          youtubeURL,
          spotifyURL,
          tiktokURL,
          twitterURL,
          amazonURL,
          websiteURL1,
          websiteURL2,
          videos,
        },
      })

      const languagesPromise = languagesSpoken.map(async (language) => {
        // Assuming every language should at least have a name
        if (language.id) {
          // Update existing language
          return await prisma.language.upsert({
            where: { id: language.id },
            update: { name: language.name },
            create: {
              name: language.name,
              user: { connect: { id: userId } },
            },
          })
        } else {
          // Create new language entry
          return await prisma.language.create({
            data: {
              name: language.name,
              user: { connect: { id: userId } },
            },
          })
        }
      })

      const experiencePromises = experiences?.map((experience) => {
        if (experience.id) {
          return prisma.experience.upsert({
            where: { id: experience.id as number },
            update: {
              companyName: experience.companyName,
              role: experience.role,
              startDate: experience.startDate,
              endDate: experience.endDate,
              duration: experience.duration,
              description: experience.description,
            },
            create: {
              companyName: experience.companyName,
              role: experience.role,
              startDate: experience.startDate,
              endDate: experience.endDate,
              duration: experience.duration ?? '',
              description: experience.description ?? '',
              user: { connect: { id: userId } },
            },
          })
        } else {
          // If no ID, create a new experience
          return prisma.experience.create({
            data: {
              companyName: experience.companyName,
              role: experience.role,
              startDate: experience.startDate,
              endDate: experience.endDate,
              duration: experience.duration ?? '',
              isCurrent: experience.isCurrent,
              description: experience.description ?? '',
              user: { connect: { id: userId } },
            },
          })
        }
      }) ?? []
      //  education
      const educationPromises = educations?.map((education) => {
        if (education.id) {
          return prisma.education.upsert({
            where: { id: education.id },
            update: {
              institutionName: education.institutionName,
              diplomaTitle: education.diplomaTitle,
              fieldOfStudy: education.fieldOfStudy,
              startDate: education.startDate,
              duration: education.duration,
              isCurrent: education.isCurrent,
              endDate: education.endDate,
            },
            create: {
              institutionName: education.institutionName,
              diplomaTitle: education.diplomaTitle,
              fieldOfStudy: education.fieldOfStudy,
              startDate: education.startDate,
              duration: education.duration ?? '',
              isCurrent: education.isCurrent,
              endDate: education.endDate,
              user: { connect: { id: userId } },
            },
          })
        } else {
          // If no ID, create a new education
          return prisma.education.create({
            data: {
              institutionName: education.institutionName,
              diplomaTitle: education.diplomaTitle,
              fieldOfStudy: education.fieldOfStudy,
              startDate: education.startDate,
              duration: education.duration ?? '',
              isCurrent: education.isCurrent,
              endDate: education.endDate,
              // Connect this new education to the user
              user: { connect: { id: userId } },
              // Add other necessary fields
            },
          })
        }
      }) ?? []

      // Handle experiences

      const expertisesPromises = expertises?.map((expertise) => {
        if (expertise.id) {
          return prisma.expertise.upsert({
            where: { id: expertise.id },
            update: {
              field: expertise.field,
              startDate: expertise.startDate,
              endDate: expertise.endDate,
              isCurrent: expertise.isCurrent,
              duration: expertise.duration,
              description: expertise.description,
            },
            create: {
              field: expertise.field ?? '',
              startDate: expertise.startDate,
              endDate: expertise.endDate,
              isCurrent: expertise.isCurrent,

              duration: expertise.duration ?? '',
              description: expertise.description ?? '',
              user: { connect: { id: userId } },
            },
          })
        } else {
          // If no ID, create a new experience
          return prisma.expertise.create({
            data: {
              field: expertise.field ?? '',
              startDate: expertise.startDate,
              endDate: expertise.endDate,
              isCurrent: expertise.isCurrent,
              duration: expertise.duration ?? '',
              description: expertise.description ?? '',
              user: { connect: { id: userId } },
            },
          })
        }
      }) ?? []

      // Await all promises together
      await Promise.all([
        userUpdatePromise,
        ...languagesPromise,
        ...experiencePromises,
        ...educationPromises,
        ...expertisesPromises,
      ])
      // Add similar awaits for experiences, educations, expertises as necessary

      return userUpdatePromise // Return the updated user info
    })

    return result
  } catch (error) {
    console.error('Failed to update user infos:', error)
    throw error
  }
}
