import { ActivatedRoute, Params } from '@angular/router';
import { Component, OnInit, ViewChild, OnDestroy, ChangeDetectorRef, ElementRef, HostListener } from '@angular/core';
import { ProductService } from '../../../../core/services/product.service';
import { ItemDTO, ReviewDTO } from '@swagger/cat';
import { Observable, of, Subject, forkJoin, combineLatest } from 'rxjs';
import { Store } from '@ngxs/store';
import { PhotoGalleryComponent, ButtonComponent } from '@libs/ui';
import { map, delay, takeUntil, switchMap, catchError, tap, filter, take } from 'rxjs/operators';
import { ProductReview } from '../../../../core/models/product-review.model';
import { ProductDisplay } from '../../../../core/models/product-display.model';
import { AddBreadcrumb, UpdateCurrentBreadcrumbName } from '../../../../core/store/actions/breadcrumb.actions';
import { ProductCheckoutComponent } from '../../components/product-checkout/product-checkout.component';
import { ProductReviewComponent } from '../../components/product-review/product-review.component';
import { OtherFormats } from '../../../../core/models/other-formats.model';
import { shrinkTitleAnimation, shrinkSecondaryAnimation, shrinkMainCard } from '../product-details/shrink.animation';
import { ProductAvailabilityService } from '../../../../core/services/product-availability.service';
import { AvailabilityDTO } from '@swagger/availability';
import { BranchSelectors } from '../../../../core/store/selectors/branch.selector';
import { ProductAvailability } from '../../../../core/models/product-availability.model';
import { CheckoutType } from '../../../../core/models/checkout-type.enum';
import { BranchDTO } from '@swagger/checkout';
import { BookImagePipe } from '../../../../pipes/book-image.pipe';
import { Review } from '../../../../core/models/review.model';
// tslint:disable-next-line: max-line-length
import { BranchesAvalabilityOverviewComponent } from '../../components/branches-avalability-overview/branches-avalability-overview.component';
import { PrinterService } from '../../../../core/services/printer.service';
import { DatePipe } from '@angular/common';
import { PrinterSelectionComponent } from '../../../../components/printer-selection/printer-selection.component';
import { SetProductIfItDoesNotExist } from '../../../../core/store/actions/product.actions';
import { RecommendationsComponent } from '../../../recommendations/recommendations.component';
import { Features } from '../../../../core/models/user.model';
import { SharedSelectors } from 'apps/sales/src/app/core/store/selectors/shared.selectors';
import { objectNotNull } from 'apps/sales/src/app/core/utils/app.utils';
import { isNullOrUndefined } from 'util';
import { SetSelectedItemIfMissingOrChanged } from 'apps/sales/src/app/core/store/actions/process.actions';
import { ProductOtherFormatsComponent } from '../../components/product-other-formats/product-other-formats.component';
import { allowedAvailabilityStatusCodes } from 'apps/sales/src/app/core/utils/product.util';

@Component({
  selector: 'app-product-details',
  templateUrl: './product-details.component.html',
  styleUrls: ['./product-details.component.scss'],
  animations: [shrinkTitleAnimation, shrinkSecondaryAnimation, shrinkMainCard],
})
export class ProductDetailsComponent implements OnInit, OnDestroy {
  @ViewChild('productDetailContainer', { read: ElementRef })
  private productDetailContainer: ElementRef<any>;
  @ViewChild('checkout') checkoutDialog: ProductCheckoutComponent;
  @ViewChild('photoGallery') photoGallery: PhotoGalleryComponent;
  @ViewChild('productReview') productReview: ProductReviewComponent;
  @ViewChild('branchesAvailabilityInfo')
  branchesAvailabilityInfo: BranchesAvalabilityOverviewComponent;
  @ViewChild('printModal') printModal: PrinterSelectionComponent;
  @ViewChild('addtocart') addToCartBtn: ButtonComponent;
  @ViewChild('recommendations') recommendations: RecommendationsComponent;
  @ViewChild('otherformats') elOtherformats: ProductOtherFormatsComponent;
  @ViewChild('panformatsel', { read: ElementRef }) public formats: ElementRef<any>;
  expanded = true;
  id: number;
  item: ItemDTO;
  destroy$ = new Subject();
  moreBtn = false;
  images$: Observable<string[]>;
  productReview$: Observable<ProductReview>;
  branches: BranchDTO[] = [];
  availability: ProductAvailability[] = [];
  _fullStars = 0;
  _halfStars = 0;
  _emptyStars = 0;
  loadBranchesInfoComponent = false;

  ssc: {
    store: { status?: string; text?: string };
    shipping: { status?: string; text?: string };
    download: { status?: string; text?: string };
  } = {
    download: {},
    shipping: {},
    store: {},
  };

  // availabilityStatus: string;
  // availabilityStatusText: string;

  get availabilityStatus() {
    return this.ssc.download.status || this.ssc.store.status || this.ssc.shipping.status;
  }

  get availabilityStatusText() {
    return this.ssc.download.text || this.ssc.store.text || this.ssc.shipping.text;
  }

  currentPickUpDate = '';
  currentDeliveryDate = '';
  storeError: string;
  deliveryError: string;
  downloadError = false;
  showFeatures = false;
  features: Features[] = [];
  detailsExpanded = false;
  showNoDescription = false;
  pickUpPrice: number;
  deliveryPrice: number;
  downloadPrice: number;

  // Desktop scroll
  showNext = false;
  showBack = false;
  showFowardContainer = false;
  showBackContainer = false;
  offset: number;
  isByEan = false;

  cartHasItems = false;
  cartHasDownload = false;
  downloadIds: number[] = [];

  fullyLoaded = false;

  private errorMessage = 'Verfügbarkeitsabfrage konnte nicht durchgeführt werden.';

  get storeError$() {
    return of(this.storeError);
  }

  get deliveryError$() {
    return of(this.deliveryError);
  }

  get fullStars() {
    return of(
      Array(this._fullStars)
        .fill(0)
        .map((x, i) => i)
    );
  }
  get halfStars() {
    return of(
      Array(this._halfStars)
        .fill(0)
        .map((x, i) => i)
    );
  }
  get emptyStars() {
    return of(
      Array(this._emptyStars)
        .fill(0)
        .map((x, i) => i)
    );
  }

  get availability$() {
    return of(this.availability);
  }

  get takeNowAvailable() {
    if (this.availability.filter((t) => t.type === CheckoutType.takeNow).length > 0) {
      return of(true);
    }
    return of(false);
  }

  get storeAvailable() {
    if (
      this.availability.filter(
        (t) =>
          t.type === CheckoutType.store &&
          (allowedAvailabilityStatusCodes(t.status) || (t.av && t.av.ssc === '830' && t.av.supplier === 'G'))
      ).length > 0
    ) {
      return of(true);
    }
    return of(false);
  }

  get shippingAvailable() {
    if (this.availability.filter((t) => t.type === CheckoutType.delivery && allowedAvailabilityStatusCodes(t.status)).length > 0) {
      return of(true);
    }
    return of(false);
  }

  get downloadAvailable() {
    if (this.availability.filter((t) => t.type === CheckoutType.donwload).length > 0) {
      return of(true);
    }
    return of(false);
  }

  get showAvLoading() {
    if (
      ((!this.storeAvLoaded || !this.shippingAvLoaded) && this.product.formatIcon !== 'EB' && this.product.formatIcon !== 'DL') ||
      (!this.downloadLoaded && (this.product.formatIcon === 'EB' || this.product.formatIcon === 'DL'))
    ) {
      return of(true);
    }
    return of(false);
  }

  get isDownload() {
    if (this.product && (this.product.formatIcon === 'EB' || this.product.formatIcon === 'DL')) {
      return of(true);
    }
    return of(false);
  }

  get productAvailable() {
    const availabilityLoaded =
      this.availability.length > 0 && ((this.storeAvLoaded === true && this.shippingAvLoaded === true) || this.downloadLoaded === true);
    const hasTakeNow = this.availability.find((t) => t.type === CheckoutType.takeNow) !== undefined;
    const hasStore = this.availability.find((t) => t.type === CheckoutType.store) !== undefined;
    const hasShipping = this.availability.find((t) => t.type === CheckoutType.delivery) !== undefined;
    const hasDownload = this.availability.find((t) => t.type === CheckoutType.donwload) !== undefined;
    const canBeBought = hasTakeNow || hasStore || hasShipping || hasDownload;
    if (canBeBought && availabilityLoaded) {
      return true;
    }
    return false;
  }

  get isGiftable() {
    return this.features.find((fet) => fet.key === 'bonus');
  }

  get isRecommendation() {
    return this.features.find((fet) => fet.key === 'recommendation');
  }

  get isSubscription() {
    return this.features.find((fet) => fet.key === 'subscription');
  }

  get inTheCartButtonDisabled() {
    if (this.product && !this.product.price) {
      return true;
    }
    const isDownload = this.product && (this.product.formatIcon === 'EB' || this.product.formatIcon === 'DL');
    const isDownloadAlreadyAdded = isDownload && this.downloadIds.includes(this.item.id);
    if (this.cartHasItems && this.cartHasDownload && isDownload && isDownloadAlreadyAdded) {
      return true;
    }
    if (isDownload && this.downloadError) {
      return true;
    }
    if (
      isDownload &&
      this.downloadLoaded &&
      this.availability.filter((t) => t.type === CheckoutType.donwload && t.quantity > 0 && allowedAvailabilityStatusCodes(t.status))
        .length < 1
    ) {
      return true;
    }
    // TODO: add logic here
    if (
      !isDownload &&
      this.storeAvLoaded &&
      this.shippingAvLoaded &&
      this.availability.filter((t) => t.type !== CheckoutType.donwload && t.quantity > 0 && allowedAvailabilityStatusCodes(t.status))
        .length < 1
    ) {
      return true;
    }
    return false;
  }

  storeAvLoaded = false;
  shippingAvLoaded = false;
  takeNowLoaded = false;
  stockInfoLoaded = false;
  downloadLoaded = false;

  readonly FULL_DESCRIPTION_LABEL = 'KLAPPENTXT';
  readonly AUTOR = 'Autor';
  readonly TITLE = 'Titel';
  readonly GENRE = 'Untertitel';
  readonly RECOMMANDED_AGE = 'reading-age';

  product: ProductDisplay;
  loadingError = false;

  constructor(
    private route: ActivatedRoute,
    private productService: ProductService,
    private productAvailabilityService: ProductAvailabilityService,
    private store: Store,
    private bookImagePipe: BookImagePipe,
    private cdrf: ChangeDetectorRef,
    private printer: PrinterService,
    private datePipe: DatePipe
  ) {}

  ngOnInit() {
    this.loadCartState();
    this.loadTempData();
    this.detailInitialize();
  }

  private detailInitialize() {
    this.route.queryParams
      .pipe(
        map((params) => {
          if (params['type'] && params['type'] === 'ean') {
            this.isByEan = true;
            return true;
          }

          return false;
        }),
        switchMap((ean) => {
          return this.route.params.pipe(
            map((params) => {
              return { id: params['id'], ean: ean };
            })
          );
        }),
        switchMap((data) => {
          this.storeAvLoaded = false;
          this.shippingAvLoaded = false;
          this.stockInfoLoaded = false;
          this.downloadLoaded = false;
          if (data.ean) {
            const item = this.productService.getItemByEan(data.id);
            return item;
          } else if (data.id) {
            return this.productService.getItemById(data.id);
          }
        }),
        catchError(() => of(null)),
        takeUntil(this.destroy$)
      )
      .subscribe((item: ItemDTO) => {
        if (this.productDetailContainer) {
          this.productDetailContainer.nativeElement.scrollTop = 0;
        }
        if (item) {
          this.availability = [];
          this.ssc = {
            download: {},
            shipping: {},
            store: {},
          };
          this.addSelectedItemToProcessIfMissingOrChanged(item);
          this.addItemIfDoesNotExistToProductState(item);
          this.item = item;
          this.product = this.productDetailMapper(item);

          if (this.product.features.length > 0) {
            this.features = this.product.features;
            this.showFeatures = true;
          }

          if (!this.product.fullDescription || (this.product.fullDescription && this.product.fullDescription.length < 1)) {
            this.showNoDescription = true;
          }

          this.processReviewData(item.reviews);
          this.loadBranches();

          if (this.product && this.product.formatIcon !== 'EB' && this.product.formatIcon !== 'DL') {
            setTimeout(() => {
              this.loadAvailability(item, item.product.ean);
            });
          } else {
            this.loadDownloadAvailability(item, item.product.ean);
          }
        } else {
          this.product = null;

          this.loadingError = true;
        }

        this.expanded = true;
        this.fullyLoaded = true;
      });
  }

  private loadTempData() {
    combineLatest([this.store.select(SharedSelectors.getProcessSelectedItem), this.route.params, this.route.queryParams])
      .pipe(takeUntil(this.destroy$), this.filterTempData)
      .subscribe((item) => {
        if (this.productDetailContainer) {
          this.productDetailContainer.nativeElement.scrollTop = 0;
        }
        this.item = item;
        this.product = this.productDetailMapper(item);
        this.product.fullDescription =
          this.product.fullDescription && this.product.fullDescription.length > 0 ? this.product.fullDescription : '  ';

        if (this.product.features.length > 0) {
          this.features = this.product.features;
          this.showFeatures = true;
        }
      });
  }

  private filterTempData = (obs: Observable<[ItemDTO, Params, Params]>): Observable<ItemDTO> => {
    return obs.pipe(
      filter(([item, params, queryParams]) => {
        if (isNullOrUndefined(item)) {
          return false;
        }

        if (queryParams['type'] && queryParams['type'] === 'ean') {
          this.isByEan = true;
          return item.product.ean === params.id;
        }
        return item.id === Number(params.id);
      }),
      map(([item, _, __]: [ItemDTO, Params, Params]) => item)
    );
  };

  private loadCartState() {
    this.store
      .select(SharedSelectors.cartHasItems)
      .pipe(
        filter((data) => !isNullOrUndefined(data) && data === true),
        take(1)
      )
      .subscribe((hasItems) => (this.cartHasItems = hasItems));

    this.store
      .select(SharedSelectors.cartHasDowloads)
      .pipe(
        filter((data) => !isNullOrUndefined(data) && data.length > 0),
        takeUntil(this.destroy$)
      )
      .subscribe((donwloadArticles) => {
        this.cartHasDownload = donwloadArticles && donwloadArticles.length > 0;
        this.downloadIds = donwloadArticles;
      });
  }

  addItemIfDoesNotExistToProductState(item: ItemDTO) {
    this.store.dispatch(new SetProductIfItDoesNotExist(item));
  }

  addSelectedItemToProcessIfMissingOrChanged(item: ItemDTO) {
    this.store.dispatch(new SetSelectedItemIfMissingOrChanged(item));
  }

  private processReviewData(review: ReviewDTO[]) {
    if (!review) {
      return;
    }

    // map to product review
    const productReview = <ProductReview>{
      id: 1,
      stars:
        review.length === 0
          ? 0
          : review
              .map((t) => t.rating)
              .reduce((total, num) => {
                return total + num;
              }) / review.length,
      employeeReviews: review.length,
      reviews: review.map((t) => {
        return <Review>{
          id: +t.id,
          author: t.author,
          content: t.text,
          title: t.title,
          stars: t.rating,
          date: new Date(t.created),
        };
      }),
    };

    // Get review information
    this.productReview$ = of(productReview).pipe(
      delay(0),
      map((pr: ProductReview) => {
        const rating = pr.stars;
        this._fullStars = Math.floor(rating);
        this._halfStars = rating > this._fullStars ? 1 : 0;
        this._emptyStars = 5 - (this._fullStars + this._halfStars);
        return pr;
      })
    );
  }

  private loadBranches() {
    this.branches = this.store.selectSnapshot(BranchSelectors.getBranchesIterable);
  }

  openBranchesAvailabilityModal() {
    this.loadBranchesInfoComponent = true;
    this.cdrf.detectChanges();
    this.branchesAvailabilityInfo.openDialog();
  }

  destroyAvailabilityModal() {
    this.loadBranchesInfoComponent = false;
    this.cdrf.detectChanges();
  }

  private productDetailMapper(item: ItemDTO): ProductDisplay {
    let fullDescription: string = null;
    let ean: string = null;
    let eanTag: string = null;
    let author: string;
    let title: string;
    let locale: string;
    let publicationDate: string;
    let format: string;
    let formatIcon: string;
    let quantity: string;
    let category: string;
    let price: number;
    let currency: string;
    let publisher: string;
    let assortment: string;
    let promoPoints: number;
    let genre = '';
    let volume = '';
    let edition = '';
    let recommandedAge = '';
    const otherFormats: OtherFormats[] = [];

    // product object mapping
    if (item.product) {
      ean = item.product.ean;
      eanTag = ean;
      locale = item.product.locale;
      publicationDate = this.formatDate(item.product.publicationDate);
      format = item.product.formatDetail;
      formatIcon = item.product.format;
      publisher = item.product.manufacturer;
      title = item.product.name;
      author = item.product.contributors;
      volume = item.product.volume;
      edition = item.product.edition;
      category = item.product.productGroup;
    }

    // text object mapping
    if (item.texts) {
      item.texts.forEach((text) => {
        const label = text.label ? '<b>' + text.label + '</b>' + '\n' + '<br>' : '';
        const value = text.value ? text.value + '\n' + '<br>' : '';
        fullDescription = fullDescription ? fullDescription + label + value : label + value;
      });
    }

    // specs object mapping
    if (item.specs) {
      genre = item.specs.find((s) => s.key === this.GENRE) ? item.specs.find((s) => s.key === this.GENRE).value : '';
      recommandedAge = item.specs.find((s) => s.key === this.RECOMMANDED_AGE)
        ? item.specs.find((s) => s.key === this.RECOMMANDED_AGE).value
        : '';
    }

    if (!!item.catalogAvailability && item.catalogAvailability.price) {
      price = item.catalogAvailability.price.value.value;
      currency = item.catalogAvailability.price.value.currency;
      this.pickUpPrice = price;
      this.deliveryPrice = price;
    }

    if (Array.isArray(item.stockInfos) && item.stockInfos.length > 0) {
      quantity = item.stockInfos[0].inStock.toString();
      if (+quantity > 0) {
        const userBranch = this.store.selectSnapshot(BranchSelectors.getUserBranch);
        for (let x = 0; x < +quantity; x++) {
          this.availability.push({
            itemId: item.id,
            branchId: +userBranch,
            quantity: +quantity,
            type: CheckoutType.takeNow,
            av: item.catalogAvailability as any,
            status: 0,
          });
        }
      }
      this.takeNowLoaded = true;
    }

    if (item.shelfInfos) {
      assortment = item.shelfInfos[0].assortment ? item.shelfInfos[0].assortment : item.shelfInfos[0].label;
    }

    if (item.family && item.family.length > 0) {
      item.family.forEach((t: ItemDTO) => {
        otherFormats.push(<OtherFormats>{
          id: t.id,
          ean: t.product.ean,
          format: t.product.format,
          formatDetail: t.product.formatDetail,
          price: !!t.catalogAvailability ? t.catalogAvailability.price.value.value : 0,
          status: !!t.catalogAvailability ? t.catalogAvailability.status : 0,
        });
      });
    }

    promoPoints = item.promoPoints;

    const imageId = item.imageId;

    const imageCover$ = this.bookImagePipe.transform(imageId);
    this.images$ = imageCover$.pipe(
      switchMap((cover) => {
        if (item.images) {
          return of([cover, ...item.images.map((t) => t.url)]);
        }
        return of([cover]);
      })
    );

    let features: Features[] = [];
    if (item.features) {
      features = item.features
        .filter((t) => t.enabled === true)
        .map((t) => {
          return <Features>{
            key: t.key,
            value: t.value,
            description: t.description,
          };
        });
    }

    return <ProductDisplay>{
      author,
      title,
      ean,
      imageId,
      eanTag,
      locale,
      publicationDate,
      format,
      formatIcon,
      quantity,
      category,
      price,
      currency,
      publisher,
      fullDescription,
      assortment,
      promoPoints,
      genre,
      volume,
      edition,
      recommandedAge,
      otherFormats,
      features,
    };
  }

  async loadDownloadAvailability(item: ItemDTO, ean: string) {
    const userBranchNumber = this.store.selectSnapshot(BranchSelectors.getUserBranch);
    const branch = this.store.selectSnapshot(BranchSelectors.getBranchesIterable).find((t) => t.branchNumber === userBranchNumber);
    if (!branch) {
      return true;
    }
    this.productAvailabilityService
      .getShippingAvailabilityWithCheck(item, ean, branch.id)
      .pipe(takeUntil(this.destroy$))
      .subscribe((response) => {
        if ((response as { error: boolean; message: string; type: CheckoutType }).error) {
          this.downloadError = true;
          this.downloadLoaded = true;
          if (this.addToCartBtn) {
            this.addToCartBtn.stopLoading();
          }
        } else {
          const successfulResponse = response as {
            branchId: number;
            type: CheckoutType;
            av: AvailabilityDTO[];
          };
          if (successfulResponse) {
            const preferredAvailability = successfulResponse.av.find((t) => t.preferred === 1 && t.supplier === 'DIG');
            if (preferredAvailability) {
              this.ssc.download = {
                status: preferredAvailability.ssc,
                text: preferredAvailability.sscText,
              };
              if (preferredAvailability.price && preferredAvailability.price.value && preferredAvailability.price.value.value) {
                this.downloadPrice = preferredAvailability.price.value.value;
              }
              this.availability.push({
                itemId: preferredAvailability.itemId,
                branchId: branch.id,
                quantity: 1,
                type: CheckoutType.donwload,
                av: preferredAvailability,
                status: +preferredAvailability.status,
              });
              this.downloadError = false;
              this.downloadLoaded = true;
              if (this.addToCartBtn) {
                this.addToCartBtn.stopLoading();
              }
            } else {
              this.downloadError = true;
              this.downloadLoaded = true;
              if (this.addToCartBtn) {
                this.addToCartBtn.stopLoading();
              }
            }
          } else {
            this.downloadError = true;
            this.downloadLoaded = true;
            if (this.addToCartBtn) {
              this.addToCartBtn.stopLoading();
            }
          }
        }
      });
  }

  async loadAvailability(it: ItemDTO, ean: string): Promise<boolean> {
    const availabilityObservables: Observable<
      { branchId: number; type: CheckoutType; av: AvailabilityDTO[] } | { error: boolean; message: string; type: CheckoutType }
    >[] = [];
    const userBranchNumber = this.store.selectSnapshot(BranchSelectors.getUserBranch);
    const branch = this.store.selectSnapshot(BranchSelectors.getBranchesIterable).find((t) => t.branchNumber === userBranchNumber);
    if (!branch) {
      return true;
    }
    this.updateStockInfo(it.id, branch.id);
    const storeAvailability = this.productAvailabilityService
      .getStoreAvailabilityWithCheck(it, ean, branch.id)
      .pipe(takeUntil(this.destroy$));
    availabilityObservables.push(storeAvailability);
    const shippingAvailability = this.productAvailabilityService
      .getShippingAvailabilityWithCheck(it, ean, branch.id)
      .pipe(takeUntil(this.destroy$));
    availabilityObservables.push(shippingAvailability);

    forkJoin(availabilityObservables)
      .pipe(
        takeUntil(this.destroy$),
        tap((t) => {
          t.map(
            (
              response:
                | {
                    branchId: number;
                    type: CheckoutType;
                    av: AvailabilityDTO[];
                  }
                | { error: boolean; message: string; type: CheckoutType }
            ) => {
              if (
                (response as {
                  error: boolean;
                  message: string;
                  type: CheckoutType;
                }).error
              ) {
                const error = response as {
                  error: boolean;
                  message: string;
                  type: CheckoutType;
                };
                if (error.type === CheckoutType.store) {
                  this.storeError = this.errorMessage;
                }
                if (error.type === CheckoutType.delivery) {
                  this.deliveryError = this.errorMessage;
                }
                return of(null);
              }
              const item = response as {
                branchId: number;
                type: CheckoutType;
                av: AvailabilityDTO[];
              };
              if (item.type === CheckoutType.store) {
                this.storeError = null;
              }
              if (item.type === CheckoutType.delivery) {
                this.deliveryError = null;
              }
              const preferredAvailability = this.getPreferedAvailability(item.av);
              if (!preferredAvailability) {
                return;
              }
              if (item.type === CheckoutType.store) {
                this.ssc.store = {
                  status: preferredAvailability.ssc,
                  text: preferredAvailability.sscText,
                };
                this.currentPickUpDate = preferredAvailability.at
                  ? this.datePipe.transform(new Date(preferredAvailability.at), 'dd.MM.yy')
                  : null;
                if (preferredAvailability.price && preferredAvailability.price.value && preferredAvailability.price.value.value) {
                  this.pickUpPrice = preferredAvailability.price.value.value;
                }
              }
              if (item.type === CheckoutType.delivery && preferredAvailability.at) {
                this.currentDeliveryDate = preferredAvailability.at
                  ? this.datePipe.transform(new Date(preferredAvailability.at), 'dd.MM.yy')
                  : null;
              }
              if (item.type === CheckoutType.delivery) {
                if (preferredAvailability.price && preferredAvailability.price.value && preferredAvailability.price.value.value) {
                  this.deliveryPrice = preferredAvailability.price.value.value;
                }
                this.ssc.shipping = {
                  status: preferredAvailability.ssc,
                  text: preferredAvailability.sscText,
                };
              }

              item.av.forEach((av) => {
                this.availability.push({
                  itemId: av.itemId,
                  branchId: item.branchId,
                  quantity: item.av.length,
                  type: item.type,
                  av: preferredAvailability,
                  status: av.status,
                });
              });
            }
          );
        })
      )
      .subscribe((av) => {
        this.storeAvLoaded = true;
        this.shippingAvLoaded = true;
        if (this.addToCartBtn) {
          this.addToCartBtn.stopLoading();
        }

        this.cdrf.detectChanges();
      });
    return true;
  }

  async updateStockInfo(itemId: number, branchId: number) {
    this.productAvailabilityService
      .getStockInfo([branchId], [itemId])
      .pipe(
        takeUntil(this.destroy$),
        map((stockInfo) => {
          if (!stockInfo) {
            return 0;
          }
          if (stockInfo.length === 1) {
            return stockInfo[0].inStock;
          }
          return stockInfo ? stockInfo.map((t) => t.inStock).reduce((s1, s2) => s1 + s2) : 0;
        })
      )
      .subscribe((inStockAv) => {
        if (inStockAv) {
          this.product.quantity = inStockAv + '';
          this.availability = this.availability.filter((t) => t.type !== CheckoutType.takeNow);
          this.availability.push({
            itemId: itemId,
            branchId: branchId,
            quantity: inStockAv,
            type: CheckoutType.takeNow,
            av: { ...this.item.catalogAvailability, qty: inStockAv } as any,
            status: 0,
          });
        }
        this.stockInfoLoaded = true;
      });
  }

  contentLoaded() {
    this.checkoutDialog.openDialog();
  }

  getPreferedAvailability(availability: AvailabilityDTO[]) {
    if (!availability) {
      return;
    }
    const preferredAvailability = availability.find((ava: AvailabilityDTO) => ava.preferred === 1);
    return preferredAvailability; // ? preferredAvailability : availability[0];
  }

  openModal() {
    if (this.productAvailable) {
      this.checkoutDialog.openDialog();
    } else {
      this.addToCartBtn.startLoading();
    }
  }

  cartActionCompleted(open: boolean) {}

  formatDate(date: Date | string): string {
    if (!!date) {
      try {
        const dateToFormat = new Date(date);
        const monthName = dateToFormat.toLocaleString('de', { month: 'long' });
        return `${monthName} ${dateToFormat.getFullYear()}`;
      } catch (error) {
        console.error(error);
        return '';
      }
    } else {
      return '';
    }
  }

  toggleMore(action: string) {
    this.moreBtn = !this.moreBtn;
    if (action === 'more') {
      this.detailsExpanded = true;
    } else {
      this.detailsExpanded = false;
    }
  }

  openGallery() {
    this.photoGallery.openDialog();
  }

  ratingInfo() {
    this.productReview.openDialog();
  }

  expand() {
    this.expanded = !this.expanded;
    this.store.dispatch(new UpdateCurrentBreadcrumbName(this.expanded ? this.product.title : 'Empfehlungen', 'product'));
    if (!this.expanded) {
      this.recommendations.loadReccomendations();
    }
  }

  async print(printer: string) {
    const printResponse = await this.printer.printProduct(this.item, printer);
    if (!printResponse.error) {
      this.printModal.closeModal();
    } else {
      this.printModal.setError(printResponse.message);
    }
  }

  printerSelect() {
    this.printModal.openDialog();
  }

  ngOnDestroy() {
    this.destroy$.next();
  }

  @HostListener('window:scroll', ['$event'])
  scrollHandler(event) {
    if (event.target.id === 'product-detail-container') {
      if (event.target.scrollTop === 0) {
        this.elOtherformats.calculateTopPosition();
      }
      if (event.target.scrollTop === event.target.scrollHeight - event.target.offsetHeight) {
        this.elOtherformats.calculateTopPosition();
      }
    }
  }
}
