(async function( $ ) {
    const $body = $( 'body' );

    /**
     * data tables initialization
     */
    window.ctp.$tables = [];
    let $dataTables = $( '[data-table]' );
    if ( $dataTables.length > 0 ) {
        $dataTables.each(function() {
            let $table = $( this );
            $table.prev( '.table-loading-skeleton' ).remove();
            let customConfig = eval('(' + $table.attr( 'data-table-config' ) + ')');
            window.ctp.$tables.push( window.ctp.utils.initializeDataTable( $table, customConfig ) );
            $table.show();
            $( window ).trigger( 'resize' );
        });
    }

    /**
     * loading skeleton
     */
    $( '.table-loading-skeleton' ).each(function() {
        let $skeleton = $( this );
        if ( $skeleton.next( '.dataTables_wrapper ' ).length === 0 ) {
            $skeleton.remove();
        }
    });

    /**
     * jquery ui date picker
     */
    $.datepicker.setDefaults();
    let $datePickers = $( '[data-date-picker]' );
    if ( $datePickers.length > 0 ) {
        $datePickers.datepicker({
            dateFormat: window.ctp.utils.dateFormat
        });
    }

    // start and end dates (jquery ui)
    let $startDatesJU = $( '[data-date-picker-start-date]' );
    if ( $startDatesJU.length > 0 ) {
        $.each( $startDatesJU, function( i, el ) {
           let $startDate = $( this ),
               identifier = $startDate.attr( 'data-date-picker-start-date' ),
               $endDate = $( `[data-date-picker-end-date="${identifier}"]` );
           // set min date on end-date
            $startDate.data( 'datepicker' ).settings.onSelect = function( selected ) {
                $endDate.data( 'datepicker' ).settings.minDate = selected;
            };
            // set max date on start-date
            $endDate.data( 'datepicker' ).settings.onSelect = function( selected ) {
                $startDate.data( 'datepicker' ).settings.maxDate = selected;
            };
        });
    }

    // start and end dates (html5 native)
    let $startDates = $( '[data-start-date]' );
    if ( $startDates.length > 0 ) {
        $.each( $startDates, function( i, el ) {
           let $startDate = $( this ),
               identifier = $startDate.attr( 'data-start-date' ),
               $endDate = $( `[data-end-date="${identifier}"]` );
            // set min date on end-date
            $startDate.on( 'change', function() {
                if ( $startDate.val() ) {
                    $endDate[0].min = $startDate.val();
                }
            });
            // set max date on start-date
            $endDate.on( 'change', function() {
                if ( $endDate.val() ) {
                    $startDate[0].max = $endDate.val();
                }
            });
        });
    }

    /**
     * jquery ui tooltips
     */
    $( '[data-toggle="tooltip"]' ).tooltip();


    /**
     * delete should require confirmation
     */
    $( '[data-delete-item]' ).on( 'click', function( e ) {
        if ( confirm( 'Do you want to delete this item?' ) ) {

        } else {
            e.preventDefault();
        }
    });
    $( '[gin-cancel-item]' ).on( 'click', function( e ) {
        if ( confirm( 'Do you want to cancel this Gin?' ) ) {

        } else {
            e.preventDefault();
        }
    });

    /**
     * toggle elements
     */
    $body.on( 'change', '[data-toggle]', function() {
        let $this = $( this );
        let targetName = $this.attr( 'data-toggle' );
        let $target = $( '[data-hidden="' + targetName + '"]' );

        // toggle on select change (with -1 as value)
        if ( $this.prop( 'tagName' ) === "SELECT" ) {
            if ( $this.val() == -1 ) {
                $target.show();
                $target.find( '[type="text"]' ).attr( 'required', 'required' );
            } else {
                $target.hide();
                $target.find( '[type="text"]' ).removeAttr( 'required' ).val( '' );
            }
        }

        // toggle on radio
        if ( $this.prop( 'tagName' ) === "INPUT" && $this.attr( 'type' ) === "radio" ) {
            // get the name to get all radios
            let radioName = $this.attr( 'name' );
            let radios = $( `[name="${radioName}"]` );
            // iterate over all data-toggle attribute values and hide all
            $.each( radios, function( i, el ) {
                let currentRadio = $( el );
                $( `[data-hidden="${currentRadio.attr( 'data-toggle' )}"]` ).hide();
            });
            // show the target
            $target.show();
        }
    });

    /**
     * check if the "other" field already exists in the dropdown
     */
    $body.on( 'keyup', '[data-hidden] [type="text"]', function() {
        let $input = $( this );
        let originSelectValues = [];
        $( '[data-toggle="' + $input.parent( '[data-hidden]' ).attr( 'data-hidden' ) + '"]' ).find( 'option' ).each(function() {
            originSelectValues.push( $( this ).text().toLowerCase() );
        });
        if ( originSelectValues.includes( $input.val().toLowerCase().trim() ) ) {
            $input.addClass( 'is-invalid' );
            $input.parents( 'form' ).find( '[type="submit"]' ).attr( 'disabled', 'disabled' );
        } else {
            $input.removeClass( 'is-invalid' );
            $input.parents( 'form' ).find( '[type="submit"]' ).removeAttr( 'disabled' );
        }
    });

    /**
     * tabs
     */
    $( '[data-tabs]' ).each(function() {
        let $tabContainer = $( this ),
            $tabPrimaryNav = $tabContainer.find( '[data-tab-nav]' ),
            $tabNavItems = $tabContainer.find( '[data-target-tab]' ),
            $tabContents = $tabContainer.find( '[data-tab]' );

        $tabNavItems.on( 'click', function( e ) {
            e.preventDefault();
            let $navItem = $tabPrimaryNav.find( `[data-target-tab="${$( this ).attr( 'data-target-tab' )}"]` ),
                $targetTab = $( `[data-tab="${$navItem.attr( 'data-target-tab' )}"]` );

            // hide all tabs and show the current one
            $tabContents.removeClass( 'active' );
            $targetTab.addClass( 'active' );

            // add active class to current nav item
            $tabNavItems.removeClass( 'active' );
            $navItem.addClass( 'active' );

            // add 'prev' class to previous nav items
            $tabNavItems.removeClass( 'prev' );
            $navItem.prevAll( '[data-target-tab]' ).addClass( 'prev' );

            // calculate width of blue line if it's a multi-step form
            // id should be present on tab primary nav for this to work
            if ( $tabContainer[0].hasAttribute( 'data-multi-step-form' ) ) {
                // find current item left coordinate
                let currentItemLeft = $tabPrimaryNav.find( '.active' ).position().left;
                // prepare a selector string for the current tab nav (the id) :after
                let currentTabNavSelectorStr = '#' + $tabPrimaryNav.attr( 'id' ) + ':after';
                // insert style tag before primary tab nav (if not present)
                let $styleTag = $( '#' + $tabPrimaryNav.attr( 'id' ) + '-style' );
                if ( $styleTag.length === 0 ) {
                    let styleStr = `${currentTabNavSelectorStr}{ width: ${currentItemLeft}px }`;
                    $tabPrimaryNav.before( `<style id="${$tabPrimaryNav.attr( 'id' )}-style">${styleStr}</style>` );
                } else {
                    $styleTag.html( `${currentTabNavSelectorStr}{ width: ${currentItemLeft}px }` );
                }
            }
        });
    });

    /**
     * focus on error
     */
    $( '[type="submit"]' ).on( 'click', function() {
        let $form = $( this ).closest( 'form' );
        let $invalid = $form.find( ':invalid' ).first();
        let href = $invalid.closest( '[data-tab]' ).attr( 'data-tab' );
        if ( !! href ) {
            $(`[data-target-tab="${href}"]`).trigger('click');
        }
    });

    /**
     * open data images in new tab on click
     */
    $body.on( 'click', '[data-inline-image-new-tab]', function( e ) {
        let $img = $( this );
        let w = window.open( '' );
        setTimeout(function() {
            w.document.write( $img[0].outerHTML );
        }, 0);
    });

    /**
     * mark required fields with *
     */
    $( '[required]' ).each(function() {
        let $input = $( this ),
            $label = $input.prev( 'label' );
        if ( $label.length > 0 ) {
            $label.text( $label.text() + '*' );
        }
    });

    /**
     * make sure that clicking on a link preserves current query params
     */
    $( '[data-preserve-params]' ).each(function() {
        let $this = $( this );
        $this.on( 'click', function( e ) {
            // check if params present
            if ( !! window.location.search ) {
                e.preventDefault();
                window.location.href = $this.attr( 'href' ) + window.location.search;
            }
        });
    });


    /**
     * item type & category select
     */
    let $containersItemTypeCategory = $( '[data-item-type-category-container]' );
    if ( $containersItemTypeCategory.length > 0 ) {
        $containersItemTypeCategory.each(function() {
            let $container = $( this ),
                $selectItemType = $container.find( '[data-item-type]' ),
                $selectItemCategory = $container.find( '[data-item-category]' ),
                $selectSubcategoryOne = $container.find( '[data-item-subcategory-one]' ),
                $selectSubcategoryTwo = $container.find( '[data-item-subcategory-two]' );

                // empty option str
                const emptyOptionStr = '<option value="" data-empty-option>Please select</option>';

            // change item category on item type select
            $selectItemType.on( 'change', async function() {
                let typeId = $selectItemType.val();
                let categoryOptions = "";
                $selectItemCategory.find( 'option' ).hide().removeAttr( 'selected' );
                if (typeId === "") {
                    $selectItemCategory.find('[data-empty-option]').prop('selected', true);
                    categoryOptions += '<option value="0">Please select</option>';
                    $("[data-item-category]").html(categoryOptions);
                } else {
                    $selectItemCategory.find(`option[data-type-id=${typeId}]`).show();
                    $selectItemCategory.find('[data-empty-option]').show().prop('selected', 'selected');
                    categoryOptions += '<option value="0">Please select</option>';

                    //category by type id
                    let categories = await $.get(`/uind/rest/uic/items/categories/${typeId}`);
                    $("[data-item-category]").html(categoryOptions);
                    for (let category of categories) {
                        categoryOptions += '<option value="' + category.id + '">' + category.title + '</option>';
                        $("[data-item-category]").html(categoryOptions);
                    }
                }

                // hide subcategory one
                $selectSubcategoryOne.find( 'option' ).hide().removeAttr( 'selected' );
                $selectSubcategoryOne.find( `option[data-type-id=${typeId}]` ).show();
                if ( $selectSubcategoryOne.find( '[data-empty-option]' ).length === 0 )
                 {
                        $selectSubcategoryOne.prepend( emptyOptionStr );
                 }
                $selectSubcategoryOne.find( '[data-empty-option]' ).show().prop( 'selected', 'selected' );
                // hide subcategory two
                $selectSubcategoryTwo.find( 'option' ).hide().removeAttr( 'selected' );
                $selectSubcategoryTwo.find( `option[data-type-id=${typeId}]` ).show();
                if ( $selectSubcategoryTwo.find( '[data-empty-option]' ).length === 0 )
                {
                      $selectSubcategoryTwo.prepend( emptyOptionStr );
                }
                $selectSubcategoryTwo.find( '[data-empty-option]' ).show().prop( 'selected', 'selected' );
            });

            // change subcategory one on category change
            $selectItemCategory.on( 'change', async function() {
                let categoryId = $selectItemCategory.val();
                //subcategories by category id
                let subCategories = await $.get( `/uind/rest/uic/items/categories/subcategory1/${categoryId}` );
                let subCategoryOptions = '<option value="0">Please select</option>';
                $( "[data-item-subcategory-one]" ).html( subCategoryOptions );
                if(subCategories.length > 0){
                for(let subCategory of subCategories)
                {
                       subCategoryOptions += '<option value="' + subCategory.id + '">' + subCategory.title + '</option>';
                       $( "[data-item-subcategory-one]" ).html( subCategoryOptions );
                }
                }
                console.log(subCategories);
                $selectSubcategoryOne.find( `option[data-parent-id=${categoryId}]` ).show();
                $selectSubcategoryOne.find( '[data-empty-option]' ).show().prop( 'selected', 'selected' );
                // hide subcategory two
                $selectSubcategoryTwo.find( 'option' ).hide().removeAttr( 'selected' );
                $selectSubcategoryTwo.find( `option[data-parent-id=${categoryId}]` ).show();
                if ( $selectSubcategoryTwo.find( '[data-empty-option]' ).length === 0 )
                {
                      $selectSubcategoryTwo.prepend( emptyOptionStr );
                }
                $selectSubcategoryTwo.find( '[data-empty-option]' ).show().prop( 'selected', 'selected' );
            });

            // change subcategory two on subcategory one change
            $selectSubcategoryOne.on( 'change', async function() {
                let subCategory1Id = $selectSubcategoryOne.val();
                //subcategories by category id
                let subCategories2 = await $.get( `/uind/rest/uic/items/categories/subcategory2/${subCategory1Id}` );
                let subCategory2Options = '<option value="0">Please select</option>';
                $( "[data-item-subcategory-two]" ).html( subCategory2Options );
                if(subCategories2.length > 0)
                {
                      for(let subCategory2 of subCategories2)
                      {
                            subCategory2Options += '<option value="' + subCategory2.id + '">' + subCategory2.title + '</option>';
                            $( "[data-item-subcategory-two]" ).html( subCategory2Options );
                      }
                }
                console.log(subCategories2);
                $selectSubcategoryTwo.find( `option[data-parent-id=${subCategory1Id}]` ).show();
                $selectSubcategoryTwo.find( '[data-empty-option]' ).show().prop( 'selected', 'selected' );
            });
        });
    }

    /**
     * search department and set company/function/department ids
     */
    let $inputsSearchDepartment = $( '[data-department-search]' );
    if ( $inputsSearchDepartment.length > 0 ) {
        $inputsSearchDepartment.each(function() {
            let $inputSearchDepartment = $( this ),
                $container = $inputSearchDepartment.closest( '[data-company-hierarchy-search-container]' ),
                $inputCompanyId = $container.find( '[data-company-search-id]' ),
                $inputFunctionId = $container.find( '[data-function-search-id]' ),
                $inputDepartmentId = $container.find( '[data-department-search-id]' );

            $inputSearchDepartment.autocomplete({
                source: '/uind/rest/hrms/departments/search',
                minLength: 1,
                select: async function ( e, ui ) {
                    $inputCompanyId.val( ui.item.companyId );
                    $inputFunctionId.val( ui.item.functionId );
                    $inputDepartmentId.val( ui.item.id );
                    setTimeout(function() {
                        $inputSearchDepartment.val( ui.item.hierarchyString );
                    }, 10 );
                },
                focus: function ( e, ui ) {
                    $inputSearchDepartment.val( '' );
                    // $inputCompanyId.val( '' );
                    // $inputFunctionId.val( '' );
                    // $inputDepartmentId.val( '' );
                }
            }).data( 'ui-autocomplete' )._renderItem = function ( ul, ui ) {
                return $( '<li>' )
                    .attr( 'data-value', ui.id )
                    .append( `<div class="ui-menu-item-wrapper">${ui.hierarchyString}</div>` )
                    .appendTo( ul );
            };
        });
    }

    /**
     * search locations
     */
    let $inputsSearchLocation = $( '[data-location-search]' );
    if ( $inputsSearchLocation.length > 0 ) {
        $inputsSearchLocation.each(function() {
            let $inputSearchLocation = $( this ),
                $container = $inputSearchLocation.closest( '[data-location-hierarchy-search-container]' ),
                $inputSiteId = $container.find( '[data-location-site-search-id]' ),
                $inputUnitId = $container.find( '[data-location-unit-search-id]' ),
                $inputFloorId = $container.find( '[data-location-floor-search-id]' ),
                $inputStoreId = $container.find( '[data-location-store-search-id]' ),
                $inputShelfId = $container.find( '[data-location-shelf-search-id]' );

            $inputSearchLocation.autocomplete({
                source: '/uind/rest/uic/locations/search',
                minLength: 1,
                select: async function ( e, ui ) {
                    $inputSiteId.val( ui.item.siteId );
                   $inputUnitId.val( ui.item.unitId );
                    $inputFloorId.val( ui.item.floorId );
                    $inputStoreId.val( ui.item.storeId );
                    $inputShelfId.val( ui.item.shelfId );
                    setTimeout(function() {
                        $inputSearchLocation.val( ui.item.hierarchyString );
                    }, 10 );
                },
                focus: function ( e, ui ) {
                    $inputSearchLocation.val( '' );
                }
            }).data( 'ui-autocomplete' )._renderItem = function ( ul, ui ) {
                return $( '<li>' )
                    .attr( 'data-value', ui.id )
                    .append( `<div class="ui-menu-item-wrapper">${ui.hierarchyString}</div>` )
                    .appendTo( ul );
            };

            // clear location id sif no text
            $inputSearchLocation.on( 'keyup', function( e ) {
                if ( $inputSearchLocation.val() === '' ) {
                    $inputSiteId.removeAttr( 'value' );
                    $inputUnitId.removeAttr( 'value' );
                    $inputFloorId.removeAttr( 'value' );
                    $inputStoreId.removeAttr( 'value' );
                    $inputShelfId.removeAttr( 'value' );
                }
            });
        });
    }

    /**
     * search sub section one
     */
    let $inputsSearchSubSections = $( '[data-company-search]' );
    if ( $inputsSearchSubSections.length > 0 ) {
        $inputsSearchSubSections.each(function() {
            let $inputSearchSubSections = $( this ),
                $container = $inputSearchSubSections.closest( '[data-company-hierarchy-search-container]' ),
                $inputCompanyId = $container.find( '[data-company-search-id]' ),
                $inputFunctionId = $container.find( '[data-function-search-id]' ),
                $inputDepartmentId = $container.find( '[data-department-search-id]' ),
                $inputSectionId = $container.find( '[data-section-search-id]' ),
                $inputSubSectionOneId = $container.find( '[data-sub-section-one-search-id]' ),
                $inputSubSectionTwoId = $container.find( '[data-sub-section-two-search-id]' );

            $inputSearchSubSections.autocomplete({
                source: '/uind/rest/hrms/companies/search',
                minLength: 1,
                select: async function ( e, ui ) {
                    $inputCompanyId.val( ui.item.companyId );
                    $inputFunctionId.val( ui.item.functionId );
                    $inputDepartmentId.val( ui.item.departmentId );
                    $inputSectionId.val( ui.item.sectionId );
                    $inputSubSectionOneId.val( ui.item.subSectionOneId );
                    $inputSubSectionTwoId.val( ui.item.subSectionTwoId );
                    setTimeout(function() {
                        $inputSearchSubSections.val( ui.item.companyHierarchyString );
                    }, 10 );
                },
                focus: function ( e, ui ) {
                    $inputSearchSubSections.val( '' );
                }
            }).data( 'ui-autocomplete' )._renderItem = function ( ul, ui ) {
                return $( '<li>' )
                    .attr( 'data-value', ui.id )
                    .append( `<div class="ui-menu-item-wrapper">${ui.companyHierarchyString}</div>` )
                    .appendTo( ul );
            };

            // clear location id sif no text
            $inputSearchSubSections.on( 'keyup', function( e ) {
                if ( $inputSearchSubSections.val() === '' ) {
                    $inputCompanyId.removeAttr( 'value' );
                    $inputFunctionId.removeAttr( 'value' );
                    $inputDepartmentId.removeAttr( 'value' );
                    $inputSectionId.removeAttr( 'value' );
                    $inputSubSectionOneId.removeAttr( 'value' );
                    $inputSubSectionTwoId.removeAttr( 'value' );
                }
            });
        });
    }

    /**
     * search item
     */
    let $inputItems = $( '[data-item-search]' );
    if ( $inputItems.length > 0 ) {
        $inputItems.each(function() {
            let $inputItem = $( this ),
                $container = $inputItem.closest( '[data-item-search-container]' ),
                $inputItemId = $container.find( '[data-item-search-id]' ),
                triggerEvent = ( typeof $inputItem.attr( 'data-trigger' ) === 'undefined' ) ? null : $inputItem.attr( 'data-trigger' );

            // search item and set id
            $inputItem.autocomplete({
                source: '/uind/rest/uic/items/search',
                minLength: 1,
                select: async function ( e, ui ) {
                    $inputItemId.val( ui.item.id ).trigger( 'change' );
                    setTimeout(function() {
                        $inputItem.val( ui.item.title );
                    }, 100 );
                    // trigger custom event
                    if ( triggerEvent != null ) {
                        $body.trigger( triggerEvent );
                    }
                },
                focus: function ( e, ui ) {
                    $inputItem.val( '' );
                    // $inputItemId.val( 0 );
                }
            }).data( 'ui-autocomplete' )._renderItem = function ( ul, ui ) {
                return $( '<li>' )
                    .attr( 'data-value', ui.id )
                    .append( `<div class="ui-menu-item-wrapper">${ui.title} (${ui.code})</div>` )
                    .appendTo( ul );
            };

            // clear item id if no text
            $inputItem.on( 'keyup', function( e ) {
                if ( $inputItem.val() === '' ) {
                    $inputItemId.removeAttr( 'value' );
                }
            });
        });
    }

    /**
    * search employee
    */
    let $inputEmployees = $( '[data-employee-search]' );
    if ( $inputEmployees.length > 0 ) {
        $inputEmployees.each(function() {
            let $inputEmployee = $( this ),
            $container = $inputEmployee.closest( '[data-employee-search-container]' ),
            $inputEmployeeUsername = $container.find( '[data-employee-search-username]' ),
            $inputEmployeeId = $container.find('[data-employee-search-id]'),
            triggerEvent = ( typeof $inputEmployee.attr( 'data-trigger' ) === 'undefined' ) ? null : $inputEmployee.attr( 'data-trigger' );

            // search employee and set id
            $inputEmployee.autocomplete({
                source: '/uind/rest/hrms/employees/search-by-username',
                minLength: 1,
                select: async function ( e, ui ) {
                    $inputEmployeeUsername.val( ui.item.username ).trigger( 'change' );
                    $inputEmployeeId.val(ui.item.id).trigger('change');
                    setTimeout(function() {
                        $inputEmployeeUsername.val( `${ui.item.username}` );
                        $inputEmployees.val( `${ui.item.concatenatedName}` );
                        $inputEmployeeId.val(`${ui.item.id}`);
                    }, 100 );
                        // trigger custom event
                    if ( triggerEvent != null ) {
                        $body.trigger( triggerEvent );
                    }
                },
                focus: function ( e, ui ) {
                    //$inputEmployee.val( `${ui.item.username} (${ui.item.id})` );
                }
            }).data( 'ui-autocomplete' )._renderItem = function ( ul, ui ) {
                return $( '<li>' )
                .attr( 'data-value', ui.title )
                .append( `<div class="ui-menu-item-wrapper">${ui.concatenatedName} (${ui.serialNumber})</div>` )
                .appendTo( ul );
                };

            // clear employee if no text
            $inputEmployee.on( 'keyup', function( e ) {
                if ( $inputEmployee.val() === '' ) {
                    $inputEmployeeUsername.removeAttr( 'value' );
                    $inputEmployeeId.removeAttr( 'value' );
                }
            });
        });
    }

    /**
     * search HOD
     */
    let $inputHod = $( '[data-hod-search]' );
    if ( $inputHod.length > 0 ) {
        $inputHod.each(function() {
            let $inputHod = $( this ),
                $container = $inputHod.closest( '[data-hod-search-container]' ),
                $inputHodUsername = $container.find( '[data-hod-search-username]' ),
                triggerEvent = ( typeof $inputHod.attr( 'data-trigger' ) === 'undefined' ) ? null : $inputHod.attr( 'data-trigger' );

            // search employee and set id
            $inputHod.autocomplete({
                source: '/uind/rest/hrms/employees/search-by-hod-username',
                minLength: 1,
                select: async function ( e, ui ) {
                    $inputHodUsername.val( ui.item.username ).trigger( 'change' );
                    setTimeout(function() {
                        $inputHodUsername.val( `${ui.item.username}` );
                        $inputHod.val( `${ui.item.concatenatedName}` );
                    }, 100 );
                    // trigger custom event
                    if ( triggerEvent != null ) {
                        $body.trigger( triggerEvent );
                    }
                },
                focus: function ( e, ui ) {
                    //$inputEmployee.val( `${ui.item.username} (${ui.item.id})` );
                }
            }).data( 'ui-autocomplete' )._renderItem = function ( ul, ui ) {
                return $( '<li>' )
                    .attr( 'data-value', ui.title )
                    .append( `<div class="ui-menu-item-wrapper">${ui.concatenatedName} (${ui.serialNumber})</div>` )
                    .appendTo( ul );
            };

            // clear employee if no text
            $inputHod.on( 'keyup', function( e ) {
                if ( $inputHod.val() === '' ) {
                    $inputHodUsername.removeAttr( 'value' );
                }
            });
        });
    }

    /**
     * search customer
     */
    let $inputCustomers = $( '[data-customer-search]' );
    if ( $inputCustomers.length > 0 ) {
        $inputCustomers.each(function() {
            let $inputCustomer = $( this ),
                $container = $inputCustomer.closest( '[data-customer-search-container]' ),
                $inputCustomerId = $container.find( '[data-customer-search-id]' ),
                triggerEvent = ( typeof $inputCustomer.attr( 'data-trigger' ) === 'undefined' ) ? null : $inputCustomer.attr( 'data-trigger' );

            // search customer and set id
            $inputCustomer.autocomplete({
                source: '/uind/rest/uic/customers/search',
                minLength: 1,
                select: async function ( e, ui ) {
                    $inputCustomerId.val( ui.item.id ).trigger( 'change' );
                    setTimeout(function() {
                        $inputCustomer.val( ui.item.title );
                    }, 100 );
                    // trigger custom event
                    if ( triggerEvent != null ) {
                        $body.trigger( triggerEvent );
                    }
                },
                focus: function ( e, ui ) {
                    $inputCustomer.val( '' );
                    // $inputCustomerId.val( 0 );
                }
            }).data( 'ui-autocomplete' )._renderItem = function ( ul, ui ) {
                return $( '<li>' )
                    .attr( 'data-value', ui.id )
                    .append( `<div class="ui-menu-item-wrapper">${ui.title} (${ui.code})</div>` )
                    .appendTo( ul );
            };

            // clear customer id if no text
            $inputCustomer.on( 'keyup', function( e ) {
                if ( $inputCustomer.val() === '' ) {
                    $inputCustomerId.removeAttr( 'value' );
                }
            });
        });
    }

    /**
     * search supplier
     */
    let $inputSuppliers = $( '[data-supplier-search]' );
    if ( $inputSuppliers.length > 0 ) {
        $inputSuppliers.each(function() {
            let $inputSupplier = $( this ),
                $container = $inputSupplier.closest( '[data-supplier-search-container]' ),
                $inputSupplierId = $container.find( '[data-supplier-search-id]' ),
                triggerEvent = ( typeof $inputSupplier.attr( 'data-trigger' ) === 'undefined' ) ? null : $inputSupplier.attr( 'data-trigger' );

            // search supplier and set id
            $inputSupplier.autocomplete({
                source: '/uind/rest/uic/suppliers/search',
                minLength: 1,
                select: async function ( e, ui ) {
                    $inputSupplierId.val( ui.item.id ).trigger( 'change' );
                    setTimeout(function() {
                        $inputSupplier.val( `${ui.item.title} (${ui.item.code})` );
                    }, 100 );
                    // trigger custom event
                    if ( triggerEvent != null ) {
                        $body.trigger( triggerEvent );
                    }
                },
                focus: function ( e, ui ) {
                    $inputSupplier.val( '' );
                    // $inputSupplierId.val( 0 );
                }

            }).data( 'ui-autocomplete' )._renderItem = function ( ul, ui ) {
                return $( '<li>' )
                    .attr( 'data-value', ui.id )
                    .append( `<div class="ui-menu-item-wrapper">${ui.title} (${ui.code})</div>` )
                    .appendTo( ul );
            };

            // clear supplier id if no text
            $inputSupplier.on( 'keyup', function( e ) {
                if ( $inputSupplier.val() === '' ) {
                    $inputSupplierId.removeAttr( 'value' );
                }
            });
        });
    }

    /**
     * search broker
     */
    let $inputBrokers = $( '[data-broker-search]' );
    if ( $inputBrokers.length > 0 ) {
        $inputBrokers.each(function() {
            let $inputBroker = $( this ),
                $container = $inputBroker.closest( '[data-broker-search-container]' ),
                $inputBrokerId = $container.find( '[data-broker-search-id]' );

            // search broker and set id
            $inputBroker.autocomplete({
                source: '/uind/rest/uic/brokers/search',
                minLength: 1,
                select: async function ( e, ui ) {
                    $inputBrokerId.val( ui.item.id ).trigger( 'change' );
                    setTimeout(function() {
                        $inputBroker.val( ui.item.title );
                    }, 100 );
                },
                focus: function ( e, ui ) {
                    $inputBroker.val( '' );
                }
            }).data( 'ui-autocomplete' )._renderItem = function ( ul, ui ) {
                return $( '<li>' )
                    .attr( 'data-value', ui.id )
                    .append( `<div class="ui-menu-item-wrapper">${ui.title}</div>` )
                    .appendTo( ul );
            };

            // clear broker id if no text
            $inputBrokers.on( 'keyup', function( e ) {
                if ( $inputBrokers.val() === '' ) {
                    $inputBrokerId.removeAttr( 'value' );
                }
            });
        });
    }

    /**
     * search transport-party
     */
    let $inputTransportParties = $( '[data-transport-party-search]' );
    if ( $inputTransportParties.length > 0 ) {
        $inputTransportParties.each(function() {
            let $inputTransportParty = $( this ),
                $container = $inputTransportParty.closest( '[data-transport-party-search-container]' ),
                $inputTransportPartyId = $container.find( '[data-transport-party-search-id]' );

            // search transport-party and set id
            $inputTransportParty.autocomplete({
                source: '/uind/rest/uic/transport-parties/search',
                minLength: 1,
                select: async function ( e, ui ) {
                    $inputTransportPartyId.val( ui.item.id ).trigger( 'change' );
                    setTimeout(function() {
                        $inputTransportParty.val( ui.item.title );
                    }, 100 );
                },
                focus: function ( e, ui ) {
                    $inputTransportParty.val( '' );
                }
            }).data( 'ui-autocomplete' )._renderItem = function ( ul, ui ) {
                return $( '<li>' )
                    .attr( 'data-value', ui.id )
                    .append( `<div class="ui-menu-item-wrapper">${ui.title}</div>` )
                    .appendTo( ul );
            };

            // clear transport-party id if no text
            $inputTransportParties.on( 'keyup', function( e ) {
                if ( $inputTransportParties.val() === '' ) {
                    $inputTransportPartyId.removeAttr( 'value' );
                }
            });
        });
    }

    /**
     * search account levels
     */
    let $inputsSearchAccountLevel = $( '[data-account-level-search]' );
    if ( $inputsSearchAccountLevel.length > 0 ) {
        $inputsSearchAccountLevel.each(function() {
            let $inputSearchLevel = $( this ),
                $container = $inputSearchLevel.closest( '[data-account-level-hierarchy-search-container]' ),
                $inputOneId = $container.find( '[data-account-level-one-search-id]' ),
                $inputTwoId = $container.find( '[data-account-level-two-search-id]' ),
                $inputThreeId = $container.find( '[data-account-level-three-search-id]' ),
                $inputFourId = $container.find( '[data-account-level-four-search-id]' );

            $inputSearchLevel.autocomplete({
                source: '/uind/rest/accounts-finance/accounts/chart-of-accounts/search/level-four',
                minLength: 1,
                select: async function ( e, ui ) {
                    $inputOneId.val( ui.item.levelOneId );
                    $inputTwoId.val( ui.item.levelTwoId );
                    $inputThreeId.val( ui.item.levelThreeId );
                    $inputFourId.val( ui.item.levelFourId );
                    setTimeout(function() {
                        $inputSearchLevel.val( ui.item.hierarchyString );
                    }, 10 );
                },
                focus: function ( e, ui ) {
                    $inputSearchLevel.val( '' );
                }
            }).data( 'ui-autocomplete' )._renderItem = function ( ul, ui ) {
                return $( '<li>' )
                    .attr( 'data-value', ui.id )
                    .append( `<div class="ui-menu-item-wrapper">${ui.hierarchyString}</div>` )
                    .appendTo( ul );
            };

            // clear account-level id sif no text
            $inputSearchLevel.on( 'keyup', function( e ) {
                if ( $inputSearchLevel.val() === '' ) {
                    $inputOneId.removeAttr( 'value' );
                    $inputTwoId.removeAttr( 'value' );
                    $inputThreeId.removeAttr( 'value' );
                    $inputFourId.removeAttr( 'value' );
                }
            });
        });
    }

    /**
     * search accounts
     */
    let $inputsSearchAccount = $( '[data-account-search]' );
    if ( $inputsSearchAccount.length > 0 ) {
        $inputsSearchAccount.each(function() {
            let $inputSearch = $( this ),
                $container = $inputSearch.closest( '[data-account-search-container]' ),
                $inputAccountId = $container.find( '[data-account-search-id]' ),
                $inputOneId = $container.find( '[data-account-level-one-search-id]' ),
                $inputTwoId = $container.find( '[data-account-level-two-search-id]' ),
                $inputThreeId = $container.find( '[data-account-level-three-search-id]' ),
                $inputFourId = $container.find( '[data-account-level-four-search-id]' );

            $inputSearch.autocomplete({
                source: '/uind/rest/accounts-finance/accounts/search',
                minLength: 1,
                select: async function ( e, ui ) {
                    $inputAccountId.val( ui.item.id );
                    $inputOneId.val( ui.item.accountLevelOneId );
                    $inputTwoId.val( ui.item.accountLevelTwoId );
                    $inputThreeId.val( ui.item.accountLevelThreeId );
                    $inputFourId.val( ui.item.accountLevelFourId );
                    setTimeout(function() {
                        $inputSearch.val( ui.item.hierarchyString );
                    }, 10 );
                },
                focus: function ( e, ui ) {
                    $inputSearch.val( '' );
                }
            }).data( 'ui-autocomplete' )._renderItem = function ( ul, ui ) {
                return $( '<li>' )
                    .attr( 'data-value', ui.id )
                    .append( `<div class="ui-menu-item-wrapper">${ui.hierarchyString}</div>` )
                    .appendTo( ul );
            };

            // clear account-level id sif no text
            $inputSearch.on( 'keyup', function( e ) {
                if ( $inputSearch.val() === '' ) {
                    $inputAccountId.val( 0 );
                    $inputOneId.removeAttr( 'value' );
                    $inputTwoId.removeAttr( 'value' );
                    $inputThreeId.removeAttr( 'value' );
                    $inputFourId.removeAttr( 'value' );
                }
            });
        });
    }

    /**
     * new cost center search and set hierarchy ids
     */
    let $inputNewCostCenterSearch = $( '[data-cost-center-search-new]' );
    if ( $inputNewCostCenterSearch.length > 0 ) {
        $inputNewCostCenterSearch.each(function() {
             window.ctp.utils.bindItemNewCostCenterSearchAutoComplete( $( this ) );
        });
    }
    /**
    /**
     * cost center search and set hierarchy ids
     */
    let $inputCostCenterSearch = $( '[data-cost-center-search]' );
    if ( $inputCostCenterSearch.length > 0 ) {
        $inputCostCenterSearch.each(function() {
             window.ctp.utils.bindItemCostCenterSearchAutoComplete( $( this ) );
        });
    }
 /*$( '[data-gin-excel]' ).on( 'click', function() {
    		let queryParams = $( '[data-filter-gin-form]' ).serialize();
    	})*/
    /**
     * toggle checked
     */
    let $togglesChecked = $( '[data-toggle-checked]' );
    $togglesChecked.each(function() {
        let $toggle = $( this );
        $toggle.on( 'click', function( e ) {
            e.preventDefault();
            // get target
            let target = $toggle.attr( 'data-toggle-checked' );
            // check all
            if ( 'all' === target ) {
                $( '[data-target-checked]' ).each(function() {
                    $( this ).prop( 'checked', true );
                });
                // check none
            } else if ( 'none' === target ) {
                $( '[data-target-checked]' ).each(function() {
                    $( this ).prop( 'checked', false );
                });
                // check individual
            } else {
                $( `[data-target-checked="${target}"]` ).each(function() {
                    $( this ).prop( 'checked', true );
                });
            }
        });
    });

    /**
     * clear brand id if the search text is removed
     */
    $body.on( 'keyup', '[data-item-brand-search]', function() {
        let $selector = $( this );
        if ( $selector.val() === '' ) {
            let $container = $selector.closest( '[data-item-brand-search-container]' );
            $container.find( '[data-item-brand-search-id]' ).removeAttr( 'value' );
        }
    });

    /**
     * clear config id if the search text is removed
     */
    $body.on( 'keyup', '[data-item-config-search]', function() {
        let $selector = $( this );
        if ( $selector.val() === '' ) {
            let $container = $selector.closest( '[data-item-config-search-container]' );
            $container.find( '[data-item-config-search-id]' ).removeAttr( 'value' );
        }
    });

    /**
     * add sidebar toggle button
     */
    let $pageFilterSidebar = $( '.page-filters-sidebar' ).closest( 'aside' );
    if ( $pageFilterSidebar.length > 0 ) {
        $body.append( `<a href="#" class="page-filter-sidebar-toggle" data-toggle-page-filter-sidebar title="Toggle Sidebar">
                            <i class="bi bi-gear"></i>
                        </a>` );

        $body.on( 'click', '[data-toggle-page-filter-sidebar]', function( e ) {
            e.preventDefault();
            $pageFilterSidebar.toggle();
            $body.trigger( 'resize' );
        });
    }

    /**
     * country/city toggle
     */
    if ( $( '[data-select-country]' ).length > 0 ) {
        $( '[data-select-country]' ).each(function() {
            let $selectCountry = $( this ),
                $selectCity = $selectCountry.closest( '[data-select-country-city-container]' ).find( '[data-select-city]' );
            // toggle city
            $selectCountry.on( 'change', function( e ) {
                let countryId = $selectCountry.val();
                // hide all cities and show related
                $selectCity.find( 'option' ).hide().removeAttr( 'selected' );
                $selectCity.find( `option[data-country-id=${countryId}]` ).show();
                $selectCity.find( '[data-empty-option]' ).show().prop( 'selected', 'selected' );
            });
        });
    }

    /**
     * select to
     */
    $( '[data-s2]' ).select2();

    /**
     * vue page sidebar app
     */
    if ( typeof Vue !== 'undefined' ) {
        // general vue app
        let vueApps = document.querySelectorAll( '[data-vue-app]' );
        if ( vueApps !== null ) {
            for ( let i = 0; i < vueApps.length; i++ ) {
                vueApps[i].setAttribute( 'data-vue-app', i );
                let vueApp = new Vue({
                    el: `[data-vue-app="${i}"]`,
                });
            }
        }
        // pay to select
        let payToApps = document.querySelectorAll( '[data-vue-pay-to-select]' );
        if ( payToApps !== null ) {
            for ( let i = 0; i < payToApps.length; i++ ) {
                payToApps[i].setAttribute( 'data-vue-pay-to-select', i );
                let vueApp = new Vue({
                    el: `[data-vue-pay-to-select="${i}"]`,
                    data: {
                        payToType: 'Supplier'
                    }
                });
            }
        }
    }

    /**
     * add custom progress
     */
    $body.on( 'click', '[data-save-custom-progress]', async function( e ) {
        const artifactType = $( '[name="artifact-change-type"]' ).val();
        const artifactId = $( '[name="artifact-change-id"]' ).val();
        const details = $( '[name="artifact-change-details"]' ).val();
        const change = await $.post( '/uind/rest/admin/artifact-changes/edit', {
            'artifact-type': artifactType,
            'artifact-id': artifactId,
            'details': details
        });
        // append to list
        const $changeList = $( '#entity-progress-list' );
        if ( $changeList.length > 0 ) {
            $changeList.prepend( `<li>${change.details} by ${change.byUser} @ ${change.dateTime}</li>` )
        } else {
            window.location.reload();
        }
    });

    /**
     * default file icon
     */


})( jQuery );