import { ChangeDetectionStrategy, Component, ElementRef, inject, OnDestroy, OnInit, signal } from '@angular/core';
import { NgIf } from '@angular/common';

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

import { CONFIG_TOKEN } from '@eui/core';
import { EuiBlockContentModule } from '@eui/components/eui-block-content';
import { EuiButtonModule } from '@eui/components/eui-button';
import { EuiLabelModule } from '@eui/components/eui-label';

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

import { @root.common.module@ as RootCommonModule } from '@root.npm.pkg@';

type StatusType = 'Loading' | 'Loaded' | 'Failed';

@Component({
    changeDetection: ChangeDetectionStrategy.OnPush,
    imports: [
        NgIf,
        EuiBlockContentModule,
        EuiButtonModule,
        EuiLabelModule,
        RootCommonModule,
    ],
    template: `
        @if (status() === 'Loaded') {
            <!-- BLOCK_CONTAINER_PLACEHOLDER -->
        }
        @if (status() === 'Loading') {
            <eui-block-content [isBlocked]="true">
                <div style="height: 100%"></div>
            </eui-block-content>
        }
        @if (status() === 'Failed') {
            <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>
        }`,
    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 {
    status = signal<StatusType | undefined>(undefined);

    block: any;

    private initSubscription: Subscription | undefined = undefined;

    private elRef = inject(ElementRef);
    private config = inject(CONFIG_TOKEN);
    private elementLifeCycleService = inject(ElementLifeCycleService);
    private elementSetupService = inject(ElementSetupService);

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

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

    loadData() {
        this.status.set('Loading');
        try {
            this.initSubscription?.unsubscribe();

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