import { LoDashStatic, times } from "lodash";


import { arxStates, tableConfigModel, dataRow, dataSource, filter, httpOption, userInfo, arxProfile } from "./arxCustomTableInterface.js";
import { getButtonsSettings } from "./arxCustomTableButton.js";



export interface arxCustomTableScope extends angular.IScope {
    //parametri per gestione caricamento configurazione
    tableLoad: boolean;
    ctrlname: string;
    tableId: string;
    pluginId: string;
    settingId: string,
    desktopId: string,
    onError: boolean;
    errorMessage: string;

    userInfo: userInfo;                     //info utente ricavate tramite arxivarUserServiceCreator
    tableConfigModel: tableConfigModel,     //model configurazione (se presente)
    states: arxStates[];                    //elenco degli stati arxivar

    newModel: boolean;              //modello nuovo?

    datasource: dataSource;          //datasource caricato
    sqlFilters: filter[];            //eventuali filtri di esecuzione valido solo per le query
    arxProfile: arxProfile;          //passo alla table un eventuale profilo nel caso di esecuzione di una vista parametrica
    docnumber: number | null;        //docnumber selezionato
    revision: number | null;         //revisione del docnubmer selezionato (se presente nel model)   

    onClickOpenModal: () => void;
    showModal: boolean;
    showGrid: boolean;
    loadingComplete: boolean;

    onClickCloseModal : () => void;

}



export class ArxCustomTable implements angular.IDirective<arxCustomTableScope> {
    restrict = 'E';
    templateUrl = './Scripts/plugins/arxCustomControls/arxCustomTable.html';
    scope = {
        tableLoad: "=",
        pluginId: "=",
        settingId: "=",
        desktopId: "=",
        sqlFilters: "=",
        docnumber: "=",
        revision: "=",
        ctrlname: "=",
        arxProfile: "=?"
    };
    private _: LoDashStatic;
    private $q: ng.IQService;
    private arxivarResourceService: IArxivarResourceService;
    private $timeout: ng.ITimeoutService;
    private $compile: ng.ICompileService;
    private pluginService: IPluginService;
    private arxivarUserServiceCreator: IArxivarUserServiceCreator;



    //static $inject = ['$scope'];

    constructor(_: LoDashStatic, $q: ng.IQService, $timeout: ng.ITimeoutService, $compile: ng.ICompileService, arxivarResourceService: IArxivarResourceService, arxivarUserServiceCreator: IArxivarUserServiceCreator, pluginService: IPluginService) {
        this._ = _;
        this.$q = $q;
        this.$timeout = $timeout;
        this.$compile = $compile;
        this.arxivarResourceService = arxivarResourceService;

        this.pluginService = pluginService;
        this.arxivarUserServiceCreator = arxivarUserServiceCreator;

    }



    controller = ['$scope', ($scope: arxCustomTableScope) => {

        $scope.showGrid = false;
        $scope.showModal = false;
        $scope.loadingComplete = false;

        //carico la configurazione
        const onInit = () => {

            const params = {
                pluginId: $scope.pluginId,
                desktopId: $scope.desktopId ?? 0,
                instanceId: $scope.settingId
            };

            //carico le informazioni 
            //sugli utenti, 
            //gli stati 
            //e il setting
            const promise: any[] = [
                getUserInfo(),
                getStates(),
                getSetting(params)
            ];

            this.$q.all(promise)
                .then(result => {

                    $scope.userInfo = result[0] as userInfo;
                    $scope.states = result[1] as arxStates[];
                    const settings = result[2];
                    //leggo la configurazione
                    $scope.onError = false;
                    //se la chiamata non ha restituito nulla significa che si tratta di un modello nuovo;
                    $scope.newModel = this._.isEmpty(settings);
                    //creo il model della documentazione;
                    $scope.tableConfigModel = {
                        newModel: $scope.newModel,
                        pluginId: $scope.pluginId,
                        configName: $scope.settingId,
                        viewId: this._.find(settings, { name: "viewId" })?.value,
                        viewParams: this._.find(settings, { name: "viewParams" })?.value,
                        sqlExternalId: this._.find(settings, { name: "sqlExternalId" })?.value,
                        sqlParams: this._.find(settings, { name: "sqlParams" })?.value,
                        archiveMask: this._.find(settings, { name: "archiveMask" })?.value,
                        columnsSettings: JSON.parse(this._.find(settings, { name: "columnsSettings" })?.value ?? "[]"),
                        buttonsSettings: this._.isEmpty(this._.find(settings, { name: "buttonsSettings" })?.value ?? "") ? getButtonsSettings() : JSON.parse(this._.find(settings, { name: "buttonsSettings" })?.value)
                    };

                    
                    //eseguo la vista come impostato nella configurazione
                    if (!this._.isNil($scope.tableConfigModel.viewId) && !this._.isEmpty($scope.tableConfigModel.viewId)) {
                        executeView($scope.tableConfigModel.viewId, $scope.tableConfigModel.viewParams, $scope.arxProfile)
                            .then(result => {
                                $scope.datasource = result.dataSource;
                                $scope.ctrlname = result.ctrlName;
                                $scope.showGrid = true;
                            })
                            .catch(error => {
                                $scope.errorMessage = error;
                                $scope.onError = true;
                                this.$timeout(() => { $scope.loadingComplete = true; }, 5000)
                            });

                    }
                    else if (!this._.isNil($scope.tableConfigModel.sqlExternalId) && !this._.isEmpty($scope.tableConfigModel.sqlExternalId)) {
                        executeSqlExternalId($scope.tableConfigModel.sqlExternalId, $scope.sqlFilters)
                            .then(result => {
                                $scope.datasource = result;
                                $scope.showGrid = true;
                            })
                            .catch(error => {
                                $scope.errorMessage = error;
                                $scope.onError = true;
                                this.$timeout(() => { $scope.loadingComplete = true; }, 5000)

                            });
                    }
                    else {
                        //tolgo la splash screen ma se non ho caricato nulla sono in errore
                        $scope.errorMessage = "Nessuna configurazione impostata";
                        $scope.onError = true;
                        this.$timeout(() => { $scope.loadingComplete = true; }, 5000)
                    }
                    

                })
                .catch(error => {
                    $scope.onError = true;
                    $scope.errorMessage = error;
                });
        };

        $scope.$on('loadingComplete', () => {
            //rimuovo lo splash screen!
            $scope.loadingComplete = true;

        });


        //creo oggetto userInfo /al momento sono nome utente e se admin
        const getUserInfo = (): ng.IPromise<userInfo> => {
            const dfrn = this.$q.defer<userInfo>();

            this.arxivarUserServiceCreator.create()
                .then(userInfo => {
                    dfrn.resolve({
                        isAdmin: !userInfo.isNotAdmin(),
                        userName: userInfo.getUserNameComplete()
                    });
                })
                .catch(error => {
                    dfrn.reject(error);
                });


            return dfrn.promise;
        };

        //recupero l'elenco degli stati possibili
        const getStates = (): ng.IPromise<arxStates[]> => {
            const dfrn = this.$q.defer<arxStates[]>();
            let statesList: arxStates[] = [];

            this.arxivarResourceService.get('states', { hideUserMessageError: true, openloader: false })
                .then(result => {
                    statesList = this._.map(result, state => {
                        return {
                            description: this._.upperCase(state.description),
                            iconClass: 'stati-' + state.iconIndex
                        };
                    });
                    //aggiungo lo stato VALID che corrisponde a VALIDO
                    statesList.push({ description: 'VALID', iconClass: this._.find(statesList, { description: 'VALIDO' })!.iconClass });
                    dfrn.resolve(statesList);
                })
                .catch(error => {
                    dfrn.reject(error);
                });
            return dfrn.promise;
        };

        //estraggo il setting specifico per la configurazione specificata
        const getSetting = (params: any): ng.IPromise<any> => {
            const dfrn = this.$q.defer<any>();

            this.pluginService.getSettings('global', params)
                .then(settings => dfrn.resolve(settings))
                .catch(error => dfrn.reject(error));
            return dfrn.promise;
        };

        //eseguo la vista e passo il data source
        const executeView = (viewId: string, viewParams?: string, arxProfile?: arxProfile): ng.IPromise<{ dataSource: dataSource, ctrlName: string }> => {
            const defer = this.$q.defer<{dataSource: dataSource, ctrlName: string }>();
           
            //in base all'id della vista, vedo se serve compilare 
            this.arxivarResourceService.get('Views/' + viewId, httpOption)
                .then(view => {
                    //se è stato valorizzato il profilo + sono specificati parametri per la vista, li imposto 
                    if (!this._.isNil(arxProfile) && !this._.isEmpty(viewParams)) {
                        //ciclo i parametri ed estraggo i valori dal profilo
                        this._.forEach(this._.split(viewParams, ';'), param => {
                            const f = this._.find(view.searchFilterDto.fields, f => f.name.toUpperCase() == param.toUpperCase());
                            const v = this._.find(arxProfile.fields, f => f.name.toUpperCase() == param.toUpperCase() || f.description.toUpperCase() == param.toUpperCase());
                            if (!this._.isNil(f) && !this._.isNil(v)) {
                                f.valore1 = v?.value
                                f.operator = 1;
                            }
                        })
                    }
                    
                    this.arxivarResourceService.getPost('v3/views', view, httpOption)
                        .then(result => { defer.resolve({ dataSource: result.data, ctrlName: view.description}); })
                        .catch(error => { defer.reject(error); });
                    
                })
            

           
            return defer.promise;
        };

        //eseguo la vista e passo il data source
        const executeSqlExternalId = (externalId: string, filters: filter[]): ng.IPromise<dataSource> => {

            const defer = this.$q.defer<dataSource>();
            const payload = {
                externalId: externalId,
                values: filters ?? [],
                filters: []
            };
            this.arxivarResourceService.getPost('SqlQueries/ExecuteByExternalId', payload, httpOption)
                .then(result => { defer.resolve(result.data); })
                .catch(error => { defer.reject(error); });

            return defer.promise;

        };
        //avvia directive
        $scope.$watch("tableLoad", (newValue) => {
            if (newValue)
                onInit();
        })

    }];

    link = (scope: arxCustomTableScope) => {

        scope.onClickOpenModal = () => {
            //mostro la grid solamente se non è in errore
            scope.showGrid = (scope.newModel || scope.onError) ? false : !scope.showGrid;
            scope.showModal = !scope.showModal;
        };

        //evento per passare alle altre directive l'info sul documento selezionato (docnumber + revisione)
        scope.$on('selectedRows', (evt, data) => {

            const dataRow: dataRow = data[0];
            scope.docnumber = dataRow?.profileInfo.docNumber ?? null;
            scope.revision = dataRow?.profileInfo.revision ?? null;
        });

        //evento di close model passato al form
        scope.onClickCloseModal = () => {
            scope.showModal = false;
            //mostro la grid solamente se non è in errore
            scope.showGrid = (scope.newModel || scope.onError) ? false : !scope.showGrid;
        }

    };


}



riesci a cmpilarmi e restituire il file di questa cosa? è un filein ts che si chiama arxCustomTables.ts