import { AfterContentInit, AfterViewInit, Component, HostListener, Input, OnDestroy, OnInit } from '@angular/core';
import { IObjectListController } from '../interfaces/object-list-controller';
import { IAction } from '../interfaces/actions/action';
import { AppLocalStorageService } from '@shared/ui-api/app-local-storage.service';
import { PaginatorService } from '@shared/ui-api/paginator.service';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { IRouteConfig } from '@shared/ui-api/interfaces/route-config/route-config';
import { IObjectListUIService } from '../interfaces/object-list-ui-service';
import { ConfigService } from '@shared/config/config.service';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-objects-view',
  templateUrl: './objects-view.component.html',
  styleUrls: ['./objects-view.component.scss'],
})
export class ObjectsViewComponent implements OnInit, OnDestroy, AfterViewInit, AfterContentInit {
  @Input() openDetailsOnClick;
  @Input() objectsListController: IObjectListController;
  @Input() objectsListUiService: IObjectListUIService;
  @Input() listOnly = false;
  currentPageSize: number;
  showLoadMore;

  cardsDisplay: boolean;
  actions: IAction[] = null;

  private itemsDisplayAsList: boolean;
  private dataSubscription: Subscription;
  private queryParamsSubscription: Subscription;
  private routerSubscription: Subscription;

  constructor(
    private appLocalStorage: AppLocalStorageService,
    private activatedRoute: ActivatedRoute,
    private router: Router,
    public paginator: PaginatorService,
    public configService: ConfigService,
  ) {
  }

  refreshData() {
    if (!this.objectsListController) {
      console.error('ObjectListController not set in objects view component.');
      return;
    }
    this.actions = this.objectsListController.actions();
    if (this.configService && this.configService.current && this.configService.current.settings) {
      this.itemsDisplayAsList = this.configService.current.settings.itemsDisplayAsList;
    }
  }

  ngOnInit() {
    this.refreshData();

    this.routerSubscription = this.router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {
        // needed because on init is not called when navigating to same page
        const navigation = this.router.getCurrentNavigation();
        if (navigation.extras.state?.menuNavigation) {
          window.scroll(0, 0);
        }
        this.refreshData();
      }
    });

    this.dataSubscription = this.activatedRoute.data.subscribe(
      routeData => {
        if (routeData.config && routeData.config.subheader) {
          const routeConfig = routeData.config as IRouteConfig;
          if (routeConfig.defaultDisplayList === true) {
            this.initCardsDisplay(false);
          } else {
            this.initCardsDisplay(!this.itemsDisplayAsList);
          }
        } else {
          this.initCardsDisplay(!this.itemsDisplayAsList);
        }
        this.setShowLoadMore();
      });
    this.queryParamsSubscription = this.activatedRoute.queryParams.subscribe(queryParams => {
      this.currentPageSize = this.paginator.getPageSizeFromQueryParams(queryParams);
    });
  }

  initCardsDisplay(defaultAsCards: boolean) {
    if (this.listOnly) {
      this.cardsDisplay = false;
    } else {
      const cardsDisplay = this.appLocalStorage.getCardsDisplay();
      if (typeof cardsDisplay === 'boolean') {
        this.cardsDisplay = cardsDisplay;
      } else {
        this.cardsDisplay = defaultAsCards === true;
      }
    }
    this.objectsListController.cardsDisplay = this.cardsDisplay;
  }

  onChangedCardsDisplay(newValue: boolean) {
    this.cardsDisplay = newValue;
    this.objectsListController.cardsDisplay = this.cardsDisplay;
  }

  setShowLoadMore() {
    this.showLoadMore = this.objectsListController &&
      (!this.objectsListController.objectList.onePage &&
        ((this.objectsListController.objectList.totalCount > this.currentPageSize) ||
          this.objectsListController.objectList.hasMore === true));
  }

  @HostListener('window:scroll', []) // for window scroll events
  onScroll() {
    const scrollPosition = window.pageYOffset;
    const scrollMax = document.documentElement.scrollHeight - document.documentElement.clientHeight;
    const scrollPercent = scrollPosition / scrollMax * 100;
    const totalObjectsCount = this.objectsListController.objectList.totalCount;
    if (scrollPercent > 99 && totalObjectsCount > this.currentPageSize) {
      this.increasePageSize();
    }
  }

  increasePageSize() {
    this.paginator.increasePageSize().then(() => {
      this.setShowLoadMore();
    });
  }

  ngAfterViewInit() {
    window.scrollTo(0, 0);
  }

  ngAfterContentInit() {
    this.setShowLoadMore();
  }

  ngOnDestroy() {
    if (this.routerSubscription) {
      this.routerSubscription.unsubscribe();
      this.routerSubscription = null;
    }
    if (this.dataSubscription) {
      this.dataSubscription.unsubscribe();
      this.dataSubscription = null;
    }
    if (this.queryParamsSubscription) {
      this.queryParamsSubscription.unsubscribe();
      this.queryParamsSubscription = null;
    }
  }
}
