import User from '#models/user'
import VerifyEmailNotification from '#mails/verify_email_notification'
import {
  issueTokenPair,
  setRefreshTokenCookie,
  isNativeClient,
} from '#controllers/access_tokens_controller'
import UserTransformer from '#transformers/user_transformer'
import type { HttpContext } from '@adonisjs/core/http'
import mail from '@adonisjs/mail/services/main'
import router from '@adonisjs/core/services/router'
import env from '#start/env'

export default class EmailVerificationController {
  async verify({ request, response, serialize }: HttpContext) {
    if (!request.hasValidSignature()) {
      return response.badRequest({ message: 'Invalid or expired verification link.' })
    }

    const userId = request.param('id') as string
    const user = await User.find(userId)

    if (!user) {
      return response.notFound({ message: 'User not found.' })
    }

    if (user.status !== 'pending') {
      return response.ok({ message: 'Email already verified.' })
    }

    user.status = 'active'
    await user.save()

    await user.load('userPref')
    await user.load('roles')
    const { accessToken, refreshToken } = await issueTokenPair(user)
    setRefreshTokenCookie(response, refreshToken)

    return serialize({
      user: UserTransformer.transform(user),
      accessToken,
      ...(isNativeClient(request) ? { refreshToken } : {}),
    })
  }

  static async sendVerificationEmail(user: User, locale: string = 'en') {
    const apiPath = router.makeSignedUrl(
      'auth.verify-email',
      { id: user.id },
      { expiresIn: '24h' }
    )

    // Signature is tied to the backend path — extract it and attach to a clean frontend URL
    const queryString = apiPath.split('?')[1] ?? ''
    const verifyUrl = `${env.get('FRONTEND_URL')}/verify-email/${user.id}?${queryString}`
    await mail.send(new VerifyEmailNotification(user, verifyUrl, locale))
  }
}
