/*
 * Copyright (C) 2017 Robert Bosch GmbH Copyright (C) 2017 Robert Bosch Manufacturing Solutions GmbH, Germany. All rights reserved.
 */

import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatTabsModule } from '@angular/material/tabs';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterModule, Routes } from '@angular/router';
import {
  AUTH_OPTIONS,
  AuthGuard,
  AuthModule,
  DefaultAuthModuleConfig,
  DefaultMacmaAuthModuleConfig,
  IAuthModuleConfig,
  IMacmaAuthModuleConfig,
  MacmaAuthModule,
} from '@bci-web-core/auth';
import { BciCoreModule, BciLayoutModule, BciSharedModule, CoreConfigurationService } from '@bci-web-core/core';
import { first, map, shareReplay, tap } from 'rxjs/operators';
import { environment } from '../environments/environment';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { Login2Component } from './login/login.component';
import { SecuredPageComponent } from './secured-page/secured-page.component';
import { from } from 'rxjs';

const appRoutes: Routes = [
  {
    path: 'login',
    component: Login2Component,
  },
  {
    path: 'home',
    component: HomeComponent,
  },
  {
    path: 'secured-page',
    component: SecuredPageComponent,
    canActivate: [AuthGuard],
  },
  {
    path: '**',
    redirectTo: 'home',
  },
];

/**
 * Please note that this code is overfly complicated for real usage, where you probably won't have to switch the auth provider dynamically.
 */
const authProviders = {
  macma: {
    module: () =>
      MacmaAuthModule.forRoot({
        authOptionsProvider: {
          provide: AUTH_OPTIONS,
          useFactory: authOptionsFactory,
        },
      }),
    defaultConfig: <IMacmaAuthModuleConfig>{
      ...DefaultMacmaAuthModuleConfig,
      autoLogin: true,
      usePopup: true,
      resourceSetName: 'ControlPanel',
      clientId: 'macma-webapp',
      defaultRealm: '7311ea8c-5d48-43fe-acf9-980eedf24b6c',
      debugAuthentication: true,
      aclReloadIntervalMs: 60000,
    },
  },
  accessControl3: {
    module: () =>
      MacmaAuthModule.forRoot({
        authOptionsProvider: {
          provide: AUTH_OPTIONS,
          useFactory: authOptionsFactory,
        },
      }),
    defaultConfig: <IMacmaAuthModuleConfig>{
      ...DefaultMacmaAuthModuleConfig,
      resourceSetName: 'ControlPanel',
      clientId: 'bci-portal-frame',
      defaultRealm: null,
      debugAuthentication: true,
    },
  },
  'access-control': {
    module: () =>
      AuthModule.forRoot({
        authOptionsProvider: {
          provide: AUTH_OPTIONS,
          useFactory: authOptionsFactory,
        },
      }),
    defaultConfig: <IAuthModuleConfig>{
      ...DefaultAuthModuleConfig,
      headerName: 'Authorization',
      authScheme: 'Bearer',
      throwNoTokenError: false,
      skipWhenExpired: false,
      resourceSetName: 'ERPConnectivity',
      automaticTokenRefresh: true,
      debugAuthentication: true,
    },
  },
};

@NgModule({
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    BciLayoutModule,
    BciSharedModule,
    FormsModule,
    RouterModule.forRoot(appRoutes, {}),
    MatFormFieldModule,
    MatInputModule,
    MatButtonModule,
    MatTabsModule,
    BciCoreModule.forRoot({
      prod_environment: environment.production,
      // For development purposes, have a look at Webpack dev server's proxy functionality to load a file from the assets only for local development without real backend.
      core_config_url: './assets/authEndpoint-macma.json',
    }),
    /* @todo TASK(177055)
    getAuthModuleImport(authProvider)
    // since angular 12 no complex function calls provided anymore */
    MacmaAuthModule.forRoot({
      authOptionsProvider: {
        provide: AUTH_OPTIONS,
        useFactory: authOptionsFactory,
        deps: [CoreConfigurationService],
      },
    }),
  ],
  declarations: [AppComponent, Login2Component, HomeComponent, SecuredPageComponent],
  bootstrap: [AppComponent],
})
export class AppModule {
}

export function authOptionsFactory(coreConfigurationService: CoreConfigurationService) {
  // You could also use a plain httpClient to load the configuration yourself if you prefer.
  const customizedConfig$ = from(coreConfigurationService.configPromise).pipe(
    // this is just demo code taking the first loaded configuration and offering to change values in prompts
    // (e.g. in case environment was changed or another one should be used)
    first(),
    tap((json) => console.log('Loaded configuration:', json)),
    map(config => {
      const endpoint = prompt('Continue with this authorization server?', config.endpoint);
      const defaultRealm = prompt('Continue with this default realm / tenant?', config.defaultRealm);
      const clientId = prompt('Continue with this client id?', config.clientId);
      return {
        ...config,
        clientId: clientId,
        endpoint: endpoint,
        defaultRealm: defaultRealm,
      };
    }),
    shareReplay(1)
  );
  return <IAuthModuleConfig>{
    ...(authProviders.macma.defaultConfig || {}),
    accessControlEndpoint: customizedConfig$.pipe(
      map(config => config.endpoint)
    ),
    clientId: customizedConfig$.pipe(
      map(config => config.clientId),
    ),
    defaultRealm: customizedConfig$.pipe(
      map(config => config.defaultRealm),
    ),
  };
}
