/**
 * This file is part of Anis Client.
 *
 * @copyright Laboratoire d'Astrophysique de Marseille / CNRS
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

import { Directive, ComponentRef, Input, Output, EventEmitter, ViewChild, OnInit, OnDestroy, Type } from '@angular/core';

import { Attribute, Dataset, Instance } from 'src/app/metamodel/models';
import { SearchQueryParams } from 'src/app/instance/store/models';
import { RendererLoaderDirective } from 'src/app/instance/search/shared-renderer/renderer-loader.directive';
import { AbstractRendererComponent } from 'src/app/instance/search/shared-renderer/abstract-renderer.component';
import { DownloadRendererComponent } from 'src/app/instance/search/shared-renderer/components';

@Directive({})
export abstract class AbstractDisplayRendererComponent implements OnInit, OnDestroy {
    @Input() rendererType: string;
    @Input() value: string | number;
    @Input() dataset: Dataset;
    @Input() instance: Instance;
    @Input() attribute: Attribute;
    @Input() queryParams: SearchQueryParams;
    @Output() downloadFile: EventEmitter<{url: string, filename: string}> = new EventEmitter();

    @ViewChild(RendererLoaderDirective, {static: true}) rendererLoaderDirective!: RendererLoaderDirective;

    public componentRef: ComponentRef<AbstractRendererComponent>;
    public rendererComponent: AbstractRendererComponent;

    ngOnInit() {
        const viewContainerRef = this.rendererLoaderDirective.viewContainerRef;
        const renderer = (this.rendererType === 'result') ? this.attribute.renderer : this.attribute.detail_renderer;
        this.componentRef = viewContainerRef.createComponent<AbstractRendererComponent>(
            this.getRendererComponent(renderer)
        );
        this.componentRef.instance.rendererType = this.rendererType;
        this.componentRef.instance.value = this.value;
        this.componentRef.instance.dataset = this.dataset;
        this.componentRef.instance.instance = this.instance;
        this.componentRef.instance.attribute = this.attribute;
        this.componentRef.instance.queryParams = this.queryParams;
        if (this.componentRef.instance instanceof DownloadRendererComponent) {
            this.componentRef.instance.downloadFile.subscribe(value => this.downloadFile.emit(value));
        }
        this.rendererComponent = this.componentRef.instance;
    }

    abstract getRendererComponent(renderer: string): Type<AbstractRendererComponent>;

    ngOnDestroy() {
        this.componentRef.destroy(); 
    }
}