import {
  emitSsoSessionAndRedirect,
  findOrCreateUserFromSso,
  nextRouteAfterSso,
} from '#services/sso_session'
import env from '#start/env'
import logger from '@adonisjs/core/services/logger'
import type { HttpContext } from '@adonisjs/core/http'

/**
 * Google SSO via @adonisjs/ally.
 *
 * Flow :
 *  1. Le SPA navigate vers GET /api/v1/auth/google/redirect
 *  2. Ally redirige vers Google avec state + scopes
 *  3. Google redirige vers GET /api/v1/auth/google/callback?code=...
 *  4. Backend matche/crée l'user (cf. findOrCreateUserFromSso),
 *     pose le refresh cookie, redirige vers /auth/sso/complete?next=...
 */
export default class AuthGoogleController {
  /** GET /api/v1/auth/google/redirect — entrée du flow OAuth. */
  async redirect(ctx: HttpContext) {
    return ctx.ally.use('google').redirect()
  }

  /** GET /api/v1/auth/google/callback — retour de Google. */
  async callback(ctx: HttpContext) {
    const google = ctx.ally.use('google')
    const webUrl = env.get('WEB_URL', 'http://localhost:5173')

    if (google.accessDenied()) {
      return ctx.response.redirect(`${webUrl}/login?google=denied`)
    }
    if (google.stateMisMatch()) {
      return ctx.response.redirect(`${webUrl}/login?google=state_mismatch`)
    }
    if (google.hasError()) {
      logger.warn({ err: google.getError() }, 'google sso error')
      return ctx.response.redirect(`${webUrl}/login?google=error`)
    }

    const googleUser = await google.user()
    if (!googleUser.email) {
      logger.warn({ id: googleUser.id }, 'google sso : email manquant')
      return ctx.response.redirect(`${webUrl}/login?google=no_email`)
    }

    const { user, isNewUser } = await findOrCreateUserFromSso({
      provider: 'google',
      providerId: googleUser.id,
      email: googleUser.email,
      fullName: googleUser.name ?? null,
    })

    const next = await nextRouteAfterSso(user, isNewUser)
    return emitSsoSessionAndRedirect(ctx, user, next, webUrl)
  }
}
