import { Injectable } from '@angular/core';
import { take } from 'rxjs/operators';
import { ConfigService } from '../config/config.service';
import { BrandingEngineService } from '../../theme/runtime/branding-engine.service';
import { ThemeEngineService } from '../../theme/runtime/theme-engine.service';
import { WidgetRegistryBootstrapService } from '../../widgets/registry/widget-registry.bootstrap.service';
import { PlatformRuntimeStateService } from './platform-runtime-state.service';
import { BootstrapConfig } from '../../shared/models/config';

@Injectable({ providedIn: 'root' })
export class PlatformRuntimeService {
  private initializing = false;

  constructor(
    private readonly configService: ConfigService,
    private readonly widgetRegistryBootstrap: WidgetRegistryBootstrapService,
    private readonly themeEngine: ThemeEngineService,
    private readonly brandingEngine: BrandingEngineService,
    private readonly runtimeState: PlatformRuntimeStateService
  ) {}

  initialize(): void {
    if (this.initializing || this.runtimeState.initialized()) {
      return;
    }

    this.initializing = true;

    this.configService.loadBootstrap().pipe(take(1)).subscribe({
      next: (bootstrap) => {
        this.widgetRegistryBootstrap.registerFromManifest().subscribe({
          next: () => {
            this.themeEngine.applyTheme(bootstrap.theme);
            this.brandingEngine.applyBranding(bootstrap.branding);
            this.runtimeState.markInitialized({
              localization: bootstrap.localization,
              featureFlags: bootstrap.featureFlags,
              permissions: bootstrap.permissions
            });
            this.initializing = false;
          },
          error: () => {
            this.themeEngine.applyTheme(bootstrap.theme);
            this.brandingEngine.applyBranding(bootstrap.branding);
            this.runtimeState.markInitialized({
              localization: bootstrap.localization,
              featureFlags: bootstrap.featureFlags,
              permissions: bootstrap.permissions
            });
            this.initializing = false;
          }
        });
      },
      error: () => {
        this.initializing = false;
      }
    });
  }

  reloadFromBootstrap(bootstrap: BootstrapConfig): void {
    this.configService.applyBootstrapOverride(bootstrap);
    this.widgetRegistryBootstrap.registerFromManifest().subscribe({
      next: () => this.applyRuntimeBootstrap(bootstrap),
      error: () => this.applyRuntimeBootstrap(bootstrap),
    });
  }

  private applyRuntimeBootstrap(bootstrap: BootstrapConfig): void {
    this.themeEngine.applyTheme(bootstrap.theme);
    this.brandingEngine.applyBranding(bootstrap.branding);
    this.runtimeState.markInitialized({
      localization: bootstrap.localization,
      featureFlags: bootstrap.featureFlags,
      permissions: bootstrap.permissions
    });
  }
}
