// Angular Core
import { Component, ElementRef, HostListener, Inject, Input, OnInit, Renderer2 } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

// Services
import { SearchService } from 'src/app/services/search/search.service';
import { SessionService } from 'src/app/services/session/session.service';
import { UtilitiesService } from 'src/app/services/utilities/utilities.service';
import { CartService } from 'src/app/services/cart/cart.service';

import { Subscription } from 'rxjs';

// Interfaces
import { searchRenderInterface } from 'src/app/interfaces/common-interfaces';

// Third Party
import { environment } from 'src/environments/environment';
import sortArray from 'sort-array';
import { DOCUMENT } from '@angular/common';
import { SessionDataInterface } from 'src/app/interfaces/session-data-interface';
import { DataTransmitterService } from 'src/app/services/dataTransmitter/data-transmitter.service';


@Component({
  standalone: false,
  selector: 'app-product-table-row-grouping',
  templateUrl: './product-table-row-grouping.component.html',
  styleUrls: ['./product-table-row-grouping.component.scss', './product-table-row-grouping.component.query.scss']
})
export class ProductTableRowGroupingComponent implements OnInit {
  
  @Input() data!: searchRenderInterface['other'][0];
  @Input() shippingInfo!: searchRenderInterface['shippingInfo'];
  @Input() fromPage: string = 'Search';

  packagesizeTooltipActive: boolean = false;
  imgUrl: string = environment.imageUrl;
  sortOrder = 'asc';
  sortColumn = '';
  sortIcon = 'long-arrow-up';
  getShoppingCartSubscribe!:Subscription;
  updateShippingInfoEvent!: Subscription;

  constructor(
    public searchService: SearchService,
    public sessionservice: SessionService,
    private utilitiesService: UtilitiesService,
    private cartService: CartService,
    public activatedRoute: ActivatedRoute,
    public renderer: Renderer2,
    private element: ElementRef,
    @Inject(DOCUMENT) private _document: Document,
    private sessionService: SessionService,
    private dataTransmitter: DataTransmitterService
  ) { }

  public groupedData: searchRenderInterface['other'][0] = [];
  session!: SessionDataInterface['data'];

  ngOnInit(): void {
    this.session = this.sessionService.getSession();
    this.updateShippingInfoEvent = this.cartService.updateShippingInfo.subscribe((data) => {
        this.setShippingInfo()
    });
    let ndc = '';
    this.groupedData = this.data.slice(0, 20);
    if (this.groupedData.length > 0 && this.groupedData[0].rx_otc !== 'Q') {
        for (let product of this.groupedData) {
            if (product.rx_otc !== 'Q' && product.ndc_clean !== '' && product.ndc_clean !== null) {
                ndc = product.ndc_clean;
                break ;
            }
        }
    }
    this.dataTransmitter.lane4AdData.next({ndc: ndc, pageName: this.fromPage});
  }

  async loadMore() {
    const next = this.groupedData.length;
    if (this.data.length !== next) {
      this.groupedData = [...this.groupedData, ...this.data.slice(next, next + 30)];
    }
  }

  @HostListener('window:scroll', ['$event'])
  onScroll(event: Event) {
    if (this.isScrollAtBottom()) {
      this.loadMore();
    }
  }

  isScrollAtBottom(): boolean {
    const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
    const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight || 0;
    const clientHeight = document.documentElement.clientHeight || window.innerHeight || 0;

    return ((scrollTop + clientHeight) + 150) >= scrollHeight;
  }

  /*
   * Adds updated cart data to shippingInfo data model
   */
  setShippingInfo() {
       let suppliers = [];
       this.getShoppingCartSubscribe = this.cartService.getShoppingCart()
        .subscribe({
            next: (res: any) => {
                const dataArray = res.data;
                if (Object.keys(res.data).length > 0) {
                     const dataArray = Object.keys(res.data).map(key => ({key, value: res.data[key]}));
                     dataArray.forEach((supplier: any) => {
                        let supplierId = supplier.key;
                        if (typeof this.shippingInfo[supplierId] !== 'undefined') {
                            this.shippingInfo[supplierId]['cutoff_time'] = supplier.value.shippingData.cutoff_time;
                            this.shippingInfo[supplierId]['shipping_methods'] = supplier.value.shippingData.shipping_methods;
                            this.shippingInfo[supplierId]['supplier_total'] = supplier.value.totalOrderAmount;
                            suppliers.push(parseInt(supplierId));
                        }
                    });
                }
            },
            error: (err) => {
            this.cartService.errorCallBack(err);
          },
          complete: () => { },
        })
  };
  /**
   * Sort dataset based on which header user has clicked and change sort icon on header.
   * @param event 
   * @param field 
   */
  customSort(event: any, field: string) {
    let element = this.element.nativeElement.querySelector('#'+field+' > div > div > i');
    this.renderer.removeClass(element, this.sortIcon);
    if (this.sortColumn !== '') {
      this.renderer.removeClass(this.element.nativeElement.querySelector('#'+this.sortColumn+' > div > div > i'), this.sortIcon);
    }
    // Toggles sort order basing the field is a previous or new one.
    if (this.sortColumn === field) {
      this.sortOrder = this.sortOrder === 'asc' ? 'desc' : 'asc';
    } else {
      this.sortOrder = 'asc';
    }
    sortArray(this.data, {
      by: field,
      order: this.sortOrder
    });
    this.sortIcon = this.sortOrder === 'asc' ? 'fa-long-arrow-up' : 'fa-long-arrow-down';
    this.sortColumn = field;
    this.groupedData = this.data.slice(0, 20);
    this.renderer.addClass(element, this.sortIcon);
  }

    /**
     * Check if rebate is shown.
     * @param itemData 
     * @returns boolean
     */
    showRebate(itemData: any) {
        return ((itemData.ipc_rebate_tier && itemData.ipc_rebate_tier != itemData.start_price) 
        || (itemData.buyer_sales_flag && this.session.trxade_gpo_member && itemData.rebate != itemData.start_price));
    }

    /*
     * Hide Unit Price if admin hide price is checked.
     * @param {type} itemData
     * @returns {Boolean}
     */
    hidePrice(product: searchRenderInterface['other'][0][0]) {
      if(product.hide_pricing === 1 && !product.account_no) {
          return true;
      }
      return false;
    }
    
    /**
     * Method to check if the Expiration Date is below 90 days or not
     * @param {string} expirationDate
     * @return {Boolean}
     */
    isExpireIn90Days(expirationDate: string) {
        return this.utilitiesService.getExpireDateBelow90Days(expirationDate);
    }
    
    ngOnDestroy() {
        this.getShoppingCartSubscribe?.unsubscribe();
        this.updateShippingInfoEvent?.unsubscribe();
    }
}