import {Component, Input, OnDestroy, OnInit} from "@angular/core";
import {TableWidget} from "../models/TableWidget";
import {DataService} from "../../../services/data.service";
import {MessageService} from "primeng/api";
import {ActivatedRoute, NavigationExtras, Router} from "@angular/router";
import {UtilsService} from "../../../services/utils.service";
import {Subscription} from "rxjs";
import {Metadata} from "../../../models/enea/ParametricQuery";
import {QueryStringParameterResolver} from "../../../services/parameter-resolvers/IParameterResolver";
import {WidgetService} from "../../../services/widget.service";
import {DialogService, DynamicDialogRef} from "primeng/dynamicdialog";
import {FormComponent} from "../../../static-pages/form/form.component";
import {TranslateService} from "@ngx-translate/core";
import {MatSortModule} from '@angular/material/sort'; 

@Component({
    selector: 'table-widget',
    templateUrl: './table-widget.component.html',
    styleUrls: ['./table-widget.component.css'],
    providers: [DialogService, MessageService]
}) 
export class TableWidgetComponent implements OnInit, OnDestroy {
    @Input() widget?: TableWidget;
    public data?: any;
    public selectedRow?: any;

    updatable: boolean = false;

    loadingData: boolean = false;
    ref?: DynamicDialogRef;

    get columns () {
        return this.data?.metadata?.filter((o: { name: string; }) => this.widget?.selectedColumns?.some(sc => sc === o?.name));
    }

    subscriptions: Subscription[] = [];

    ngOnDestroy() {
        for (const subscription of this.subscriptions)
            if (subscription)
                subscription.unsubscribe();
        this.subscriptions = [];
    }

    constructor(private widgetService: WidgetService,
                public dialogService: DialogService,
                private dataService: DataService,
                private utilsService: UtilsService,
                private messageService: MessageService,
                private route: ActivatedRoute,
                private translateService: TranslateService,
                private router: Router,
                private utils: UtilsService) {}

    ngOnInit(): void {
        this.setUpdatable();
    	this.loadData();
        this.listenForConfigurationChanged();
        this.listenForRouteChanged();
        
    }


    private setUpdatable(){
        for (let param of this.widget?.datasourceConfiguration?.parameters!){
            if(param.type === "any_date_choosen_by_user")  this.updatable = true; 
        }
    }

    private loadData() {
        const isWellConfigured =
            !!this.widget?.datasourceConfiguration?.parametricQuery &&
            this.widget?.datasourceConfiguration?.parametricQuery?.metadata?.length > 0;

        if (!this.widget?.datasourceConfiguration) {
            this.utils.showErrorMessage("No datasourceConfigurated");
            return;
        }

        if (!isWellConfigured){
            this.utils.showErrorMessage("Datasource not well configured");
           return;
        }

        if (!this.dataService.areParametersFilled(this.widget?.datasourceConfiguration)){
            this.utils.showErrorMessage("Not all parameters are filled  ");
            return;
        }
           
       
        
        this.loadingData = true;
        this.subscriptions.push(this.dataService.getData(this.widget?.datasourceConfiguration).subscribe(response => {
            this.loadingData = false;
            this.data = response;
        }, error => this.loadingData = false));
    }

    listenForConfigurationChanged() {
        const subscription = this.widgetService.onConfigurationChanged.subscribe(tableWidget => {
            if (tableWidget !== this.widget)
                return;
            this.loadData();
        });
        this.subscriptions.push(subscription);
    }

    updateData(){
        this.loadData();
    }

    listenForRouteChanged() {
        this.subscriptions.push(this.route.queryParams.subscribe(params => {
            for (const param in params)
                if (params.hasOwnProperty(param) && this.widgetListensForParamName(param)) {
                    /**
                     * NOTA: si può migliorare la gestione, attualmente se la tabella è legata
                     * ad almeno un parametro presente in querystring viene ricaricata.
                     * E' possibile tenere conto degli ultimi valori con i quali è stata caricata
                     * in modo da evitare il caricamento se la tabella ascolta sul parametro A e B
                     * ma è cambiato invece il parametro C (che non dovrebbe richiedere invece il
                     * caricamento della tabella)
                     */
                    this.loadData();
                    return;
                }
        }));
    }

    private widgetListensForParamName(paramName?: string): boolean {
        if (!paramName)
            return false;

        const queryStringParameters = this.widget?.datasourceConfiguration?.parameters
            .filter(o => o.type === new QueryStringParameterResolver().type) || [];
        return queryStringParameters.filter(o => o.value === paramName || (!o.value && o.name === paramName)).length > 0;
    }

    onRowSelect(event: any) {
        console.info("Selected ROW: ", event.data);
        this.utils.showInfoMessage("Selected ROW: " + JSON.stringify (event.data));
        if (!this.widget?.rowSelectColumn)
            return;

        const paramName = this.widget.rowSelectParamName ?? this.widget.rowSelectColumn;
        const paramValue = event.data[this.widget.rowSelectColumn];

        // this.utilsService.showInfoMessageTrans()
        this.messageService.add({severity:'info', summary:'Riga selezionata', detail: paramValue});

        this.navigateToCurrentUrlUsing(paramName, paramValue);

        // this.widgetService.onRowSelectionDone.next(<RowSelectionInfo> {
        //     widget: this.widget,
        //     paramName: paramName
        // });
    }

    navigateToCurrentUrlUsing(name: string, value: any){

        let queryParams: any = {};
        queryParams[name] = value;

        if (this.widget?.rowSelectTarget) {
            //In this case, the target is decided by the administrator and I can move to the target when row is selected
            let navigationExtras: NavigationExtras = {
                queryParams: queryParams
              };
              console.log("redirecting the user to: " + this.widget?.rowSelectTarget!);
              console.log(queryParams);
              // Redirect the user

              this.router.navigate(["/pages/" + this.widget?.rowSelectTarget!], {
                relativeTo: this.route,
                queryParams: queryParams,
                queryParamsHandling: 'merge',  // preserve the existing query params in the route
                //skipLocationChange: true // do not trigger navigation
            });
              //this.router.navigateByUrl("pages/" + this.widget?.rowSelectTarget!, navigationExtras);
        }
        else{
            //in this case, only a parameter value is selcted and assigned
        
            
              
            


        // changes the route without moving from the current view or
        // triggering a navigation event,
        this.router.navigate([], {
            relativeTo: this.route,
            queryParams: queryParams,
            queryParamsHandling: 'merge',  // preserve the existing query params in the route
            //skipLocationChange: true // do not trigger navigation
        });
        }
    }

    formatCell(column: Metadata, value: any) {
        if (column.type === "Integer")
            return value;
        if (column.type === "Timestamp" || column.type === "Date")
            try {
                return new Date(value).toLocaleString("it-IT");
            }
            catch {
                return value + " #ERROR#";
            }
        if (column.type === "String" && value && value.match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}[+-]\d{2}:\d{2}/g))
            new Date(value).toLocaleString("it-IT");

        return value;
    }

    create() {
        this.translateService.get("TABLE_WIDGET.DIALOG_TITLE_CREATE").subscribe(value =>
            this.ref = this.dialogService.open(FormComponent, {
                data: {code: this.widget?.formCode ?? ""},
                header: value,
                width: '70%',
                contentStyle: {"max-height": "100%", "overflow": "auto"},
                baseZIndex: 10000
            })
        );
    }

    edit(rowData: any) {
        this.ref = this.dialogService.open(FormComponent, {
            data: {code: this.widget?.formCode ?? "", row: rowData, id: rowData ? rowData[this.widget?.formColumnId ?? ""] : null},
            header: this.widget && this.widget.formColumnTitle ? rowData[this.widget.formColumnTitle] : "",
            width: '70%',
            contentStyle: {"max-height": "100%", "overflow": "auto"},
            baseZIndex: 10000
        })
    }
}