// Angular Core
import { Component, Input, OnInit } from '@angular/core';
import { Data } from '@angular/router';

// Interfaces
import { StaticFilters, advancedFilterInterface } from 'src/app/interfaces/user/user-search';

// Services
import { SearchService } from 'src/app/services/search/search.service';
import { SupplierCatalogService } from 'src/app/services/supplierCatalog/supplier-catalog.service';

@Component({
  standalone: false,
  selector: 'app-advanced-filter',
  templateUrl: './advanced-filter.component.html',
  styleUrls: ['./advanced-filter.component.scss']
})
export class AdvancedFilterComponent implements OnInit {

    @Input() advancedConfig!: advancedFilterInterface['config'];
    @Input() filters!: advancedFilterInterface['staticFilters'];
    @Input() searchtype!: advancedFilterInterface['searchtype'];

  constructor(private searchService:SearchService, private supplierCatalogService:SupplierCatalogService) { }

    ngOnInit(): void {
        this.config = Object.assign(this.advancedConfig, this.myConfig);
        /**
         * Listener to uncheck all static filters
         */
        this.searchService.uncheckAllStaticFilters.subscribe(() => {
            if(!this.unCheckAllRunning){
                this.unCheckAll();
            }
        });

        this.searchService.setAdvanceFilterOpenFlag.subscribe(() => {
            if (this.config.keepOpen) {
                this.config.keepOpen = false;
            }
        });

        this.searchService.checkSupplierFilterListener.subscribe(() => {
            this.filters.supplier?.forEach((filter: StaticFilters['supplier'][0]) => {
                if (!filter.hide_supplier) {
                    this.clickCheckBox('supplier', filter);
                }
            });
        });

        /**
         * Listen for checkShortDateFilter event and check short date filters.
         * @type EventListener
         */
        this.searchService.checkShortDataFilter.subscribe((shortDateFilter: StaticFilters['shortDate']) => {
            this.filters.shortDate?.forEach((filter: StaticFilters['shortDate'][0]) => {
                if (shortDateFilter.indexOf(filter) !== -1) {
                    this.clickCheckBox('shortDate', filter)
                }
            });
        });
    }

    isSuppFilterSelected!: boolean;
    /**
     * For select All filter option for all fields.
     */
    myConfig: advancedFilterInterface['config'] = {
        purchasedBefore: false,
        selectAllFilter:[
            {
                filter: -1,
                name: ' Select All',
                count: 0
            },
            {
                filter: -2,
                name: ' Select All',
                count: 0
            },
            {
                filter: -3,
                name: ' Select All',
                hide_supplier: 1,
                count: 0
            },
            {
                filter: -4,
                name: ' Select All',
                count: 0
            },
            {
                filter: -5,
                name: ' Select All',
                count: 0
            },
            {
                filter: -6,
                name: ' Select All',
                count: 0
            },
            {
                filter: -7,
                name: ' Select All',
                count: 0
            },
            {
                filter: -8,
                name: ' Select All',
                count: 0
            },
            {
                filter: -9,
                name: ' Select All',
                count: 0
            },
            {
                filter: -10,
                name: ' Select All',
                count: 0
            },
            {
                filter: -11,
                name: ' Select All',
                count: 0
            }
        ] 
    };

    /**
     * Toggle Purchased Before filter
     * @param event Event from checkbox
     */
    togglePurchasedBefore(event: Event): void {
        const checked = (event.target as HTMLInputElement).checked;

        this.config.purchasedBefore = checked;

        // service state
        this.searchService.setPurchasedBefore(checked);

        // UI-only sync (optional)
        if (this.searchService.searchQuery?.searchData?.staticFilters) {
            this.searchService.searchQuery.searchData.staticFilters.purchasedBefore = checked;
        }
    }


    // searchtype:any;
    supplierId:any;
    // filters:any;
    config!: any
    /**
     * check/unchecks checkbox, also process necessary changes to search service
     * @param {string} filterName
     * @param {object} filter
     * @returns {undefined}
     */
    clickCheckBox (filterName:string, filter: any) {
        if(filter.isChecked) {
            if(typeof(filter.filter) =='number' && filter.filter < 0) {
                this.unCheckAllByName(filterName);
            } else {
                filter.isChecked = !filter?.isChecked;
            }
        } else {
            if(typeof(filter.filter) == 'number' && filter.filter < 0) {
                //check all checkboxes of that filterName
                this.checkAllByName(filterName);
            } else {
                filter.isChecked = !filter?.isChecked;
            }   
        }
        if(this.isFilterFull(filterName)) {
            this.checkAllByName(filterName);
        } else {
            this.unCheckSelectAllByName(filterName);
            this.setSelectedFilters(filterName);
        }
    };

    /**
     * Unchecks the select all option 
     * @param {type} filterName
     * @returns {undefined}
     */
    unCheckSelectAllByName(filterName:string) {
        var arr = this.getFilterByName(filterName);
        arr[0].isChecked = false;
    };

    /**
     * Sets filters
     * @param {type} filterName
     * @returns {undefined}
     */
    setSelectedFilters (filterName:string) {
        var arr = this.getFilterByName(filterName);
        if(this.searchtype === 'search') {
            this.searchService.setFilterArr(filterName, []);
        }
        else {
            this.searchService.setSpecificSearchFilterArr(filterName, []);
        }
        arr.forEach((filter: StaticFilters['shortDate'][0]) => {
            if(filter.isChecked) {
                if (typeof (filter.filter) == 'number'){
                    if (filter.filter >= 0)
                    {
                        if(this.searchtype === 'search') {
                            this.searchService.addFilterSelection(filterName, filter.filter);
                        }
                        else {
                            this.searchService.addSpecificSearchFilterSelection(filterName, filter.filter);
                        }
                    }
                } else {
                    if(this.searchtype === 'search') {
                        this.searchService.addFilterSelection(filterName, filter.filter);
                    }
                    else {
                        this.searchService.addSpecificSearchFilterSelection(filterName, filter.filter);
                    }
                }
            }
        });
    };

    /**
     * Gets count of selections on specific filter
     * @param {type} filterName
     * @returns {Number}
     */
    countSelectedByName (filterName: string) {
        var filter = this.getFilterByName(filterName);
        var count = 0;
        filter.forEach((arr:any) => {
            if(arr.isChecked) {
                if (typeof(arr.filter) == 'number'){
                    if (arr.filter >= 0)
                    {
                        count++;
                    }
                } else {
                    count++;
                }
            }
        });
        return count;
    };

    /**
     * determines if filter is selected full
     * @param {type} filterName
     * @returns {Boolean}
     */
    isFilterFull (filterName:any) {
        var filter = this.getFilterByName(filterName);
        var countSelected = this.countSelectedByName(filterName);
        var fullSelectedLength = filter.length - 1;
        // If all items are selected and the current filter is not 'ADD' (represented by -7), return true
        if(countSelected === fullSelectedLength && filter[0]['filter'] !== -7) {
            return true;
        }
        return false;
    };

    /**
     * checks all filters on a specified fieldname
     * @param {string} filterName
     * @returns {undefined}
     */
    checkAllByName (filterName:any) {
        this.supplierId = this.supplierCatalogService.getSupplierId();
        let filterArr = this.getFilterByName(filterName);
        filterArr.forEach((filter:any) => {
            filter.isChecked = true;
        });
        let searchTypes = ['supplier', 'ADR', 'cntrlSchedules', 'productCategory'];
        let filterNames = ['ADR', 'cntrlSchedules', 'productCategory'];
        if(this.searchtype === 'search') {
            this.searchService.setFilterArr(filterName, []);
            if (searchTypes.indexOf(filterName) !== -1) {
                filterArr.forEach((filter:any) => {
                    if (filter.filter > 0 || ['adr', 'brandOrGeneric'].indexOf(filter.filter) !== -1) {
                        this.searchService.addFilterSelection(filterName, filter.filter);
                    }
                });
            }
        }
        else if(this.searchtype==='suppliercatalog') {
            this.searchService.setSpecificSearchFilterArr(filterName, []);
            if (filterNames.indexOf(filterName) !== -1) {
                this.addFiltersToSpecificSearch(filterName, filterArr);
            }
            this.isSupplierFilterSelected();
            if (this.isSuppFilterSelected === false || filterName === 'supplier') {
                this.searchService.setFilterArr('supplier', []);
                filterArr = this.getFilterByName('supplier');
                this.addFiltersToSpecificSearch('supplier', filterArr);
            }
            this.searchService.setSupplierCatalogId(this.supplierId);
        }
        else if(this.searchtype==='MostPopularBrands' || this.searchtype==='TopWacSpreadBrands') {
            this.searchService.setSpecificSearchFilterArr(filterName, []);
            if (filterNames.indexOf(filterName) !== -1) {
                this.addFiltersToSpecificSearch(filterName, filterArr);
            }
        }
        else {
            this.searchService.setSpecificSearchFilterArr(filterName, []);
            if (searchTypes.indexOf(filterName) !== -1) {
                this.addFiltersToSpecificSearch(filterName, filterArr);
            }
        }
    };

    isSupplierFilterSelected() {
        this.isSuppFilterSelected = false;
        this.filters.supplier.forEach((filter: any) => {
            if (filter.isChecked === true) {
                this.isSuppFilterSelected = true;
            }
        })
    };

    addFiltersToSpecificSearch (filterName:any, filterArr:any) {
        filterArr.forEach((filter:any) => {
            if (filter.filter > 0 || filter.filter === 'adr' || (filterName === 'productCategory' && isNaN(filter.filter))) {
                this.searchService.addSpecificSearchFilterSelection(filterName, filter.filter);
            }
        });
    };

    /**
     * unchecks all filters on a specified fieldname
     * @param {string} filterName
     * @returns {undefined}
     */
    unCheckAllByName (filterName:string) {
        var filterArr = this.getFilterByName(filterName);
        filterArr.forEach((filter:any) => {
            filter.isChecked = false;
        });
        if(this.searchtype==='search') {
            this.searchService.setFilterArr(filterName, []);
        }
        else {
            this.searchService.setSpecificSearchFilterArr(filterName, []);
        }
    };

    /**
     * Gets the filter by its name
     * @param {string} filterName
     * @returns {Array|filter}
     */
    getFilterByName (filterName:string) {
        return (this.filters as Data)[filterName];
    };

    /**
     * Clears all filters
     * @returns {undefined}
     */
    clearAll() {
        if(this.searchtype==='search') {
            this.searchService.resetFilters();
        }
        else if(this.searchtype==='suppliercatalog') {
            this.searchService.resetSpecificSearchFilters();
            this.searchService.setSupplierCatalogId(this.supplierId);
        }
        else {
            this.searchService.resetSpecificSearchFilters();
        }

        // Reset purchasedBefore
        this.config.purchasedBefore = false;
        this.searchService.setPurchasedBefore(false);

        this.applyFilters(false);
        this.unCheckAll();
        if(this.searchtype==='suppliercatalog') {
            this.supplierId = this.supplierCatalogService.getSupplierId();
            this.searchService.setSupplierCatalogId(this.supplierId);
        }
    };

    /**
     * Flag to avoid unecessary digest cicles because of event listener
     */
    unCheckAllRunning: boolean = false;

    /**
     * Unchecks all selected filters and removes them from the search query
     * @returns {undefined}
     */
    unCheckAll () {
        this.unCheckAllRunning = true;
        var filters = this.filters;
        var filter;
        for (filter in filters) {
            if (filter !== 'supplier') {
                this.unCheckAllByName(filter);
            }
        }
        this.unCheckAllRunning = false;
    };

    /**
     * cancels the advance filter and clears all checks
     * @returns {undefined}
     */
    cancel() {
        this.unCheckAll();

        // Reset purchasedBefore
        this.config.purchasedBefore = false;
        this.searchService.setPurchasedBefore(false);

        this.close();
    }

    /**
     * closes the advanced filter
     * @returns {undefined}
     */
    close (){
        this.config.show = false;
        this.config.keepOpen = false;
    };

    /**
     * toggles keep open state
     * @returns {undefined}
     */
    clickKeepOpen () {
        this.config.keepOpen = !this.config.keepOpen;
    };
        
    /**
     * triggers new search with current filters state
     * @returns {undefined}
     */
    applyFilters(filterSelected: boolean) {
        
        this.searchService.calculatePagination = true;
        this.isSupplierFilterSelected();
        if(this.searchtype==='suppliercatalog' && (this.countSelectedByName('supplier') === 0 || this.isSuppFilterSelected === false)) {
            this.searchService.setFilterArr('supplier', []);
            var filterArr = this.getFilterByName('supplier');
            this.addFiltersToSpecificSearch('supplier', filterArr);
        }
        if(this.searchtype==='search') {
            this.searchService.setAdvFilterSelected.emit(filterSelected);
        }
        this.searchService.setSearchPageNumber(1);
        this.searchService.setSpecificSearchPageNumber(1);
        
        this.searchService.searchQuery.searchData.searchOptions.filters['purchasedBefore'] = this.searchService.getPurchasedBefore();
        this.searchService.searchQuery.searchData.staticFilters['purchasedBefore'] = this.searchService.getPurchasedBefore();

        this.searchService.searchBySearchQuery.emit({});
        this.searchService.supplierSearchBySearchQuery.emit({});
        this.searchService.shortDatedSearchBySearchQuery.emit({});
        this.searchService.oppBuysSearchBySearchQuery.emit({});               
        this.searchService.dealsProductsSearchQuery.emit({});
        this.searchService.brandsSearchBySearchQuery.emit({});
        this.searchService.gpoDealsProductsSearchQuery.emit({});
        this.searchService.drugShortageSearchQuery.emit({});
        this.searchService.otcCatagorySearchQuery.emit({});
        this.searchService.diabeticSuppliesSearchQuery.emit({});
        this.searchService.controlsSearchQuery.emit({});
        if(!this.config.keepOpen) {
            this.close();
        }
    };
}
