'use server'

// refresh token

import React from 'react'
import { prisma } from '@/lib/prisma'
import { appointmentType } from '@/types/calendarTypes'
//  register appointement

export const registerAppointement = async (
  appointment: any,
  expert_refresh_token: string,
  replies,
  userId,
  appointmentKey
) => {
  try {
    console.log('From adding appointment')

    const existingAppointment = await prisma.appointment.findUnique({
      where: {
        appointmentKey: appointment.appointmentKey,
      },
      select: {
        paymentStatus: true,
      },
    })
    // If an appointment exists, handle accordingly (e.g., return a message)
    if (
      existingAppointment &&
      existingAppointment.paymentStatus !== 'NotPaid'
    ) {
      console.log('An appointment with this key already exists.')
      return
      // Or return some response indicating the appointment already exists
    }
    console.log('From adding appointment 1')

    const newAppointment = await prisma.appointment.upsert({
      where: {
        appointmentKey: appointment.appointmentKey, // Assuming `appointmentKey` is your unique identifier
      },
      create: {
        ...appointment, // Spread the appointment object for creation
      },
      update: {
        ...appointment, // Spread the appointment object for updates
      },
    })

    for (const [questionId, content] of Object.entries(replies)) {
      const numericQuestionId = parseInt(questionId, 10)
      const questionContent = await fetchQuestionContentById(numericQuestionId)

      if (questionContent) {
        await prisma.reply.create({
          data: {
            content: content as string,
            questionContent: questionContent,
            appointment: {
              connect: { appointmentKey },
            },
            user: {
              connect: { id: userId },
            },
          },
        })
      }
    }

    console.log('From adding appointment 2')

    const clientId = appointment.clientId

    // const {clientData:refresh_token} = await prisma.user.findUnique({
    //   where: { id: clientId },
    //   select: { refreshToken: true } // Assuming refreshToken is stored in the user model
    // });

    // const client_refresh_token = clientData?.refreshToken;

    let expert_access_Token

    if (process.env.GOOGLE_CLIENT_ID! && process.env.GOOGLE_APP_SECRET!) {
      const expert_response = await fetch(
        'https://oauth2.googleapis.com/token',
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
          },
          body: new URLSearchParams({
            client_id: process.env.GOOGLE_CLIENT_ID!,
            client_secret: process.env.GOOGLE_APP_SECRET!,
            refresh_token: expert_refresh_token, // Replace with the actual refresh token
            grant_type: 'refresh_token',
          }),
        }
      )

      // const client_response = await fetch(
      //   'https://oauth2.googleapis.com/token',
      //   {
      //     method: 'POST',
      //     headers: {
      //       'Content-Type': 'application/x-www-form-urlencoded',
      //     },
      //     body: new URLSearchParams({
      //       client_id: process.env.GOOGLE_CLIENT_ID,
      //       client_secret: process.env.GOOGLE_APP_SECRET,
      //       refresh_token: client_refresh_token, // Replace with the actual refresh token
      //       grant_type: 'refresh_token',
      //     }),
      //   }
      // )

      console.log('From adding appointment 3')

      const expert_data = await expert_response.json()
      // const client_data = await client_response.json()

      expert_access_Token = expert_data.access_token
      // client_access_Token = client_data.access_token
      // console.log({ expert_data })
    }
    await createCalendarEvent(expert_access_Token, appointment)
    // await createCalendarEvent(client_access_Token, appointement)
    console.log('done', newAppointment)

  } catch (err) {
    console.log({ err })
  }
}

// Function to fetch question content by its ID
async function fetchQuestionContentById(questionId) {
  const question = await prisma.question.findUnique({
    where: {
      id: questionId,
    },
  })
  return question ? question.content : null
}

const createCalendarEvent = async (
  accessToken: string,
  appointment: appointmentType
) => {
  try {
    // console.log({ accessToken })
    const appointmentKey = appointment.appointmentKey
    const timeZone = appointment.timezone

    const appointmentStartDate = new Date(appointmentKey)

    // Adding one hour to the start date
    const appointmentEndDate = new Date(
      appointmentStartDate.getTime() + 60 * 60 * 1000
    )

    // Event details format based on Google Calendar API requirements
    const eventDetails: any = {
      summary: 'Appointment',
      description: appointment.text,
      start: {
        dateTime: appointmentKey,
        timeZone, // Replace with actual timezone
      },
      end: {
        dateTime: appointmentEndDate.toISOString(),
        timeZone, // Replace with actual timezone
      },

      reminders: {
        useDefault: false,
        overrides: [
          { method: 'email', minutes: 24 * 60 }, // 24 hours before the event
          { method: 'email', minutes: 60 }, // 30 minutes before the event
          { method: 'email', minutes: 15 }, // 30 minutes before the event
        ],
      },
    }

    const response = await fetch(
      `https://www.googleapis.com/calendar/v3/calendars/primary/events`,
      {
        method: 'POST',
        headers: {
          Authorization: `Bearer ${accessToken}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(eventDetails),
      }
    )

    // console.log('done', await response.json())

    return await response.json()
  } catch (err) {
    console.log({ err })
  }
}

// fetch calendar Evenets
export const fetchCalendarEvents = async (expert_refresh_token: string) => {
  console.log('from fetch events')
  const calendarId = 'primary' // Use 'primary' for the user's primary calendar
  const timeMin = new Date().toISOString() // Fetch events starting from now

  const url = `https://www.googleapis.com/calendar/v3/calendars/${encodeURIComponent(
    calendarId
  )}/events?timeMin=${encodeURIComponent(timeMin)}`

  let expert_access_Token

  try {
    //  get access token

    if (process.env.GOOGLE_CLIENT_ID! && process.env.GOOGLE_APP_SECRET!) {
      const expert_response = await fetch(
        'https://oauth2.googleapis.com/token',
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
          },
          body: new URLSearchParams({
            client_id: process.env.GOOGLE_CLIENT_ID!,
            client_secret: process.env.GOOGLE_APP_SECRET!,
            refresh_token: expert_refresh_token, // Replace with the actual refresh token
            grant_type: 'refresh_token',
          }),
        }
      )

      // console.log('from fetch events 2 ', { expert_response })

      const expert_data = await expert_response.json()
      // const client_data = await client_response.json()

      expert_access_Token = expert_data.access_token

      //  fetch events
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          Authorization: `Bearer ${expert_access_Token}`,
          Accept: 'application/json',
        },
      })

      console.log('from fetch events 3 events fetched ', { response })
      //
      if (!response.ok) {
        throw new Error(`Error: ${response.status}`)
      }

      const data = await response.json()

      // console.log({ data })

      // console.log(
      //   'events',
      //   data.items.map((item: any, index: number) => {
      //     console.log({ item })
      //   })
      // )
      return data.items // array of calendar events
    }
  } catch (error) {
    console.error('Error fetching calendar events', error)
    throw error
  }
}

// Fetch appointement from Prisma
export async function getAppointmentsForExpert(expertId: string) {
  try {
    const appointments = await prisma.appointment.findMany({
      where: {
        expertId: expertId,
      },
      // Include additional fields as needed
      // include: {
      //   expert: true, // Include expert details
      //   // ... include other relations if necessary
      // },
    })
    // console.log({ appointments })
    return appointments
  } catch (error) {
    console.error('Error fetching appointments:', error)
    throw error // or handle the error as needed
  }
}
