'use server'

import { redirect } from 'next/navigation'
import { decode } from 'decode-formdata'
import { object, string, email, minLength, safeParse } from 'valibot'
import { auth, createSession, facebook, linkedIn } from '@/auth/lucia'
import { generateCodeVerifier, generateState } from 'arctic'
import { cookies } from 'next/headers'
import { google } from '@/auth/oauth'
import { first } from 'lodash'
import { user } from '@/types/userType'
import nodemailer from 'nodemailer';
import { generateEmailVerificationToken } from '@/auth/token'


const transporter = nodemailer.createTransport({
  host: 'mail.mybestcall.io', // Outgoing mail server (SMTP)
  port: 465,                  // SMTP port for SSL
  secure: true,               // Use SSL
  auth: {
    user: 'donotreply@mybestcall.io',
    pass: process.env.PASS,
  },
} as nodemailer.TransportOptions);


// Function to send an email
export const sendEmailVerificationLink = async (data: { email: string, token: string; }) => {
  try {

    const htmlContent = `
        <!DOCTYPE html><html><head><title>My Best Call</title></head><body><h1>My Best Call Contact Us</h1><p> 
        Your verification link: <br>
        https://mybestcall.io/email-verification/${data.token}
        <br>
        </p></body></html>`;

    const info = await transporter.sendMail({
      from: '"My Best Call" <donotreply@mybestcall.io>',
      to: data.email,
      subject: "email verification",
      html: htmlContent as string
    });

    console.log('Email sent: %s', info.messageId);
  } catch (error) {
    console.error('Error sending email:', error);
  }
};

// creating the user
export const createUser = async (prop: any, formData: FormData) => {
  const data = decode(formData)
  const result = safeParse(SignupSchema, data);
  console.log(result);

  // const result = data

  if (!result.success) {
    // return valiError(result.issues)
    throw new Error("error");
  }

  const { user, err: userErr } = await signUp(result.output, prop.invitationId as string | undefined)

  let redirects = {
    url: '',
  }

  console.log('------->', userErr)
  console.log('------->', userErr?.message)

  if (userErr?.message.includes('AUTH_DUPLICATE')) {
    return { email: 'Email already registered' }
  }

  if (userErr) {
    return { message: 'Email already registered' }
  }

  // make the default language english
  const newLang = await prisma?.language.create({
    data: {
      name: 'English',
      userId: user.userId,
    },
  })

  await createSession(user?.userId)

  redirect(process.env.WEBSITE_URL ?? '/')
}

const SignupSchema = object({
  email: string([email('Please provide a valid email.')]),
  firstName: string(),
  lastName: string(),
  countryOfResidence: string(),
  password: string([minLength(6, 'Must be atleast 6 characters long.')]),
})

export const signUp = async (data: any, invitationId?: string) => {
  try {
    const { email, password } = data;

    const user: user = await auth.createUser({
      key: {
        providerId: 'email',
        providerUserId: email.toLowerCase(),
        password: password,
      },
      attributes: { email, emailVerified: invitationId ? true : false, isExpert: invitationId ? true : false, firstName: data.firstName, lastName: data.lastName, countryOfResidence: data.countryOfResidence },
    })

    if (!invitationId) {
      const token = await generateEmailVerificationToken(user.userId);
      await sendEmailVerificationLink({ email: user.email, token: token });
    }

    if (invitationId) {

      // update the user

      const updatedUser = await prisma?.user.update({
        where: {
          id: user.userId
        },
        data: {
          isExpert: true
        }
      });

      const expert = await prisma?.expert.create({
        data: {
          isAccepted: true,
          User: { connect: { id: user.userId } }
        },
        include: {
          User: true
        }
      });


      const invitation = await prisma?.admin_invite_experts.update({
        where: {
          id: invitationId
        },
        data: {
          status: "ACCEPTED"
        }
      })

      // create notification
      const notification = await prisma?.admin_notification.create({
        data: {
          title: "Invitation Accepted",
          description: `${user.firstName} ${user.lastName} has accepted your invitation`,
        }
      })

      const notificationStatus = await prisma?.admin_notification_status.update({
        where: {
          id : 1
        },
        data: {
          status: "NOTSEEN"
        }
      })

    }

    return { user }
  } catch (err) {
    console.log({ err })

    return { err: err as Error }
  }
}


export const createGoogleAuthorizationURL = async () => {
  try {
    const state = generateState()
    const codeVarifier = generateCodeVerifier()

    cookies().set('codeVerifier', codeVarifier, {
      httpOnly: true,
    })
    cookies().set('state', state, {
      httpOnly: true,
    })

    const authorizationURL = await google.createAuthorizationURL(
      state,
      codeVarifier,
      { scopes: ['email', 'profile'] }
    )
    console.log('url', authorizationURL)
    return {
      successs: true,
      data: authorizationURL,
    }
  } catch (error) {
    return {
      error: error?.message,
    }
  }

  // const tokens = await google.validateAuthorizationCode(code);
}

export const createFacebookAuthorizationURL = async () => {
  try {
    const state = generateState()

    cookies().set('state', state, {
      httpOnly: true,
    })

    const authorizationURL = await facebook.createAuthorizationURL(state, {
      scopes: ['email', 'public_profile'],
    })
    console.log('url', authorizationURL)
    return {
      successs: true,
      data: authorizationURL,
    }
  } catch (error) {
    return {
      error: error?.message,
    }
  }
}

export const createLinkedInAuthorizationURL = async () => {
  try {
    const state = generateState()

    cookies().set('state', state, {
      httpOnly: true,
    })

    const authorizationURL = await linkedIn.createAuthorizationURL(state, {
      scopes: ['email', 'profile'],
    })
    console.log('url', authorizationURL)
    return {
      successs: true,
      data: authorizationURL,
    }
  } catch (error) {
    return {
      error: error?.message,
    }
  }
}
