import { HttpClient } from '@angular/common/http';
import { inject } from '@angular/core';
import type { CanActivateFn } from '@angular/router';
import { Router } from '@angular/router';
import { environment } from 'environments/environment';
import { catchError, map, of } from 'rxjs';
import type { OAuthTokens } from '../shared/authentication.types';
import { TokenStore } from '../shared/token-store.service';

export const authorizationCodeCallbackGuard: CanActivateFn = (route) => {
  const http = inject(HttpClient);
  const router = inject(Router);
  const tokenStore = inject(TokenStore);
  const code = route.queryParamMap.get('code');
  const state = route.queryParamMap.get('state');

  if (!code) {
    return of(router.createUrlTree(['/']));
  }

  return http.post<OAuthTokens>(`${environment.api.rest}/auth/token`, { code, state }).pipe(
    map((credentials) => {
      tokenStore.setCredentials(credentials);
      const redirectURL = route.queryParamMap.get('redirectURL') ?? '/';
      return router.createUrlTree([redirectURL]);
    }),
    catchError(() => {
      // Navigate to a dedicated error page via the Angular Router so the user
      // sees a clear failure message. We deliberately do NOT set
      // window.location.href back to the hub launcher here: auto-relaunching
      // would create an infinite authorize → callback → fail → relaunch loop
      // and trigger the backend ThrottlerGuard 429. Only an explicit user
      // action (the "Try again" button on /callback-error) may start a new
      // authorize round-trip.
      return of(router.createUrlTree(['/callback-error']));
    }),
  );
};
