import { NgModule, Injector, DoBootstrap, ApplicationRef } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClient, HttpClientModule, HttpHeaders } from '@angular/common/http';
import { createCustomElement } from '@angular/elements';

import { StoreModule, USER_PROVIDED_META_REDUCERS } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import { StoreRouterConnectingModule } from '@ngrx/router-store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';

import { TranslateModule } from '@ngx-translate/core';

import {
    CoreModule,
    CONFIG_TOKEN,
    EUI_CONFIG_TOKEN,
    translateConfig,
} from '@eui/core';
import { EUI_COMPONENTS_MODULES } from './eui-components';
import {
    CsdrCoreModule,
    ElementStorageService,
} from '@csdr/core';

import { TOKEN, reducerProvider, metaReducers, runtimeChecks } from './reducers/index';
import { CustomSerializer } from './reducers/custom-route-serializer';

import { environment } from '../environments/environment';
import { appConfig } from '../config';

import { @root.common.module@ as RootCommonModule } from '@root.npm.pkg@';
import {
    DEFAULT_MAPPED_PROVIDERS,
} from '@csdr/integration/element';
import { RoutingModule } from './routing.module';

import { FallbackComponent } from './fallback.component';
import { ModuleComponent } from './module.component';

// IMPORTS

// DECLARATIONS

@NgModule({
    imports: [
        BrowserModule,
        BrowserAnimationsModule,
        HttpClientModule,
        StoreRouterConnectingModule.forRoot({ stateKey: 'router', serializer: CustomSerializer }),
        EffectsModule.forRoot([]),
        StoreDevtoolsModule.instrument({ name: appConfig.global.storeName, maxAge: 150, logOnly: environment.production }),
        TranslateModule.forRoot(translateConfig),

        CoreModule.forRoot(),
        CsdrCoreModule.forRoot(),
        RootCommonModule,
        RoutingModule,
        ...EUI_COMPONENTS_MODULES,

       // DEFINITIONS
    ],
    declarations: [
        FallbackComponent,
        ModuleComponent,
    ],
    entryComponents: [
        FallbackComponent,
        ModuleComponent,
    ],
    providers: [
        reducerProvider,
        {
            provide: EUI_CONFIG_TOKEN,
            useValue: { appConfig: { ...appConfig, ...environment }, environment },
        },

        ...DEFAULT_MAPPED_PROVIDERS,

        // PROVIDERS
    ],
})
export class AppModule implements DoBootstrap {

    constructor(private injector: Injector, private http: HttpClient) {
        // CONSTRUCTOR DECLARATIONS
    }

    ngDoBootstrap(appRef: ApplicationRef): void {
        const elementSampleEui = createCustomElement(ModuleComponent, { injector: this.injector });
        try {
            customElements.define(appConfig.global.elementName, elementSampleEui);
        } catch (e) {
            console.log(e);
        }
    }
}
