import { Component, OnInit, Inject, ElementRef, OnDestroy } from '@angular/core';

import { Subscription } from 'rxjs';
import { first } from 'rxjs/operators';

import { CONFIG_TOKEN } from '@eui/core';
import { ElementSetupService, ElementLifeCycleService } from '@csdr/integration/element';

enum ElementStatus {
    Loading = 'loading',
    Loaded = 'loaded',
    Error = 'error',
}

@Component({
    template: `
        <eui-block-content *ngIf="moduleStatus === ElementStatus.Loading" [isBlocked]="true">
            <div style="height: 100%"></div>
        </eui-block-content>
        <ng-container *ngIf="moduleStatus === ElementStatus.Loaded">
            <router-outlet></router-outlet>
        </ng-container>
        <ng-container *ngIf="moduleStatus === ElementStatus.Error">
            <div class="error-container">
                <div>
                    <h1>Translations or user data for this module failed to load.</h1>
                    <p>Do you want to try again?</p>
                    <button euiButton euiPrimary (click)="loadData()">
                        <span euiLabel>{{ 'global.RELOAD' | translate }}</span>
                    </button>
                </div>
            </div>
        </ng-container>
    `,
    styles: [`
        .error-container {
            width: 50vw;
            height: 50vh;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }

        .error-container div {
            text-align: center
        }
    `],
})
export class ModuleComponent implements OnInit, OnDestroy {
    ElementStatus = ElementStatus;
    moduleStatus: ElementStatus;

    private initSubscription: Subscription;

    constructor(private elRef: ElementRef,
                @Inject(CONFIG_TOKEN) public config: any,
                private elementLifeCycleService: ElementLifeCycleService,
                private elementSetupService: ElementSetupService) {
    }

    ngOnInit() {
        const elementData = this.elementLifeCycleService.getElementData(this.elRef);
        this.elementLifeCycleService.setup(elementData);
        this.loadData();
    }

    ngOnDestroy(): void {
        this.initSubscription?.unsubscribe();
        this.elementLifeCycleService.cleanup();
    }

    private loadData() {
        this.setStatus(ElementStatus.Loading);
        try {
            this.initSubscription?.unsubscribe();

            this.initSubscription = this.elementSetupService
                .init()
                .pipe(first())
                .subscribe((loadStatus: { success: boolean; error?: string }) => {
                    if (!loadStatus.success) {
                        this.setStatus(ElementStatus.Error);
                        console.error(`[ELEMENT: ${this.config.global.elementName}] `, loadStatus.error);
                    } else {
                        this.setStatus(ElementStatus.Loaded);
                    }
                });
        } catch (e) {
            console.log(e);
            this.setStatus(ElementStatus.Error);
        }
    }

    private setStatus(status: ElementStatus) {
        this.moduleStatus = status;
    }
}
