import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Router, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';
import { map } from 'rxjs/operators';
import { ConfigService } from '../config/config.service';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard  {
  constructor(private authService: AuthService, private config: ConfigService, private router: Router) {
  }

  // TODO: extend this to perform feature check on routes too
  canActivate(
    route: ActivatedRouteSnapshot, state: RouterStateSnapshot
  ): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    return this.authService.checkIfLoggedIn().pipe(map(isAuthenticated => {
      const isLoginPage = (route.routeConfig.path === 'login' ||
        route.routeConfig.path === 'login/:invitationId/:invitationToken');
      const isSSOPage = (route.routeConfig.path === 'sso') || (route.routeConfig.path === 'saml2sso');
      const isTosPreview = route.routeConfig.path === 'terms-of-service-preview/:id';
      const isRegisterPage = (route.routeConfig.path === 'signup' ||
        route.routeConfig.path === 'signup/:email/:invitationId/:invitationToken');
      const isResetPage = route.routeConfig.path === 'reset';
      const isNewPasswordPage = route.routeConfig.path === 'reset-password/:userid/:token';
      const isLogoutPage = route.routeConfig.path === 'logout';
      const sfaRelated = route.routeConfig.path === 'sfa';
      const isCartPage = state.url.indexOf('billing/cart') > 0;
      const isOrderPage = state.url.indexOf('billing/order') > 0 && this.authService.feature('ui.enduser');
      const isRegisterDomainPage = state.url.indexOf('domains/register-domain') > 0;

      const unauthenticatedExceptions = (
        isSSOPage || isResetPage || isNewPasswordPage || sfaRelated || isRegisterPage || isTosPreview || isCartPage ||
        isRegisterDomainPage || isOrderPage
      );

      if (!isAuthenticated && isLogoutPage) {
        return this.router.parseUrl(this.config.getPanelUrl('login'));
      }

      if (isAuthenticated &&
        (isLoginPage || isResetPage || isNewPasswordPage || isRegisterPage || isTosPreview)) {
        // should not be available to already authenticated users
        return this.router.parseUrl(this.config.getPanelHomeUrl());
      }
      if (route.data.config && route.data.config.feature) {
        if (this.authService.userData.features[route.data.config.feature] === false) {
          return this.router.parseUrl(this.config.getPanelUrl('404'));
        }
      }
      if (!isAuthenticated && unauthenticatedExceptions) {
        return true;
      }
      if (!isAuthenticated && !isLoginPage) {
        // we are not authenticated, and we are not on login page, redirect to login page
        // save current url, so we can redirect back after login
        this.config.setActiveUrl(state.url);
        const nextUrl = this.config.checkNextUrl(state.url);
        return this.router.parseUrl(
          this.config.getPanelUrl('login') + (nextUrl ? `?nextUrl=${nextUrl}` : '')
        );
      }

      if (isAuthenticated) {
        if (this.authService.userData?.is_development && Math.ceil(Math.random() * 50) === 1) {
          console.error(
            'Fleio is running with a development license and is not authorized for production usage. ' +
            'Please report any cases of abuse to abuse@fleio.com.',
          );
        }
      }

      return true;

    }));
  }
}
