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'

/**
 * Microsoft 365 SSO via le custom Ally driver (services/ally/microsoft_driver.ts).
 *
 * Flow identique à Google (cf. AuthGoogleController). Le tenant utilisé
 * est défini dans config/ally.ts (par défaut `common` : couvre les comptes
 * work/school + comptes personnels Microsoft).
 */
export default class AuthMicrosoftController {
  /** GET /api/v1/auth/microsoft/redirect — entrée OAuth. */
  async redirect(ctx: HttpContext) {
    return ctx.ally.use('microsoft').redirect()
  }

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

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

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

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

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