import { Component, OnInit, OnDestroy, signal, HostListener, ChangeDetectionStrategy, inject } from '@angular/core';
import { ActivatedRoute, RouterLink } from '@angular/router';
import { CartService } from '../../services';
import { PrefetchService } from '../../services/prefetch.service';
import { Item } from '../../models';
import { Subscription } from 'rxjs';
import { getDiscountedPrice, getMainImage, trackByItemId, getBadgeClass, getTranslatedField } from '../../utils/item.utils';
import { LanguageService } from '../../services/language.service';
import { LangRoutePipe } from '../../pipes/lang-route.pipe';
import { TranslatePipe } from '../../i18n/translate.pipe';
import { SCROLL_THRESHOLD_PX, SCROLL_DEBOUNCE_MS, ITEMS_PER_PAGE } from '../../config/constants';
import { ProductFacade } from '../../facades/platform/product.facade';
import { ProductCardComponent } from '../../components/product-card/product-card.component';
import { IconComponent } from '../../shared/ui/icon/icon.component';
import { SkeletonComponent } from '../../shared/ui/skeleton/skeleton.component';

@Component({
  selector: 'app-category',
  imports: [RouterLink, LangRoutePipe, TranslatePipe, ProductCardComponent, IconComponent, SkeletonComponent],
  templateUrl: './category.component.html',
  styleUrls: ['./category.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class CategoryComponent implements OnInit, OnDestroy {
  categoryId = signal<number>(0);
  items = signal<Item[]>([]);
  loading = signal(false);
  error = signal<string | null>(null);
  hasMore = signal(true);
  
  private skip = 0;
  private readonly count = ITEMS_PER_PAGE;
  private isLoadingMore = false;
  private routeSubscription?: Subscription;
  private scrollTimeout?: ReturnType<typeof setTimeout>;
  private readonly productFacade = inject(ProductFacade);

  constructor(
    private route: ActivatedRoute,
    private cartService: CartService,
    private prefetchService: PrefetchService
  ) {}

  ngOnInit(): void {
    this.routeSubscription = this.route.params.subscribe(params => {
      const id = parseInt(params['id'], 10);
      this.categoryId.set(id);
      this.resetAndLoad();
    });
  }

  ngOnDestroy(): void {
    this.routeSubscription?.unsubscribe();
    if (this.scrollTimeout) clearTimeout(this.scrollTimeout);
  }

  resetAndLoad(): void {
    this.items.set([]);
    this.skip = 0;
    this.hasMore.set(true);
    this.loadItems();
  }

  loadItems(): void {
    if (this.isLoadingMore || !this.hasMore()) return;

    this.loading.set(true);
    this.isLoadingMore = true;

    this.productFacade.getProductsByCategory(this.categoryId(), { count: this.count, skip: this.skip }).subscribe({
      next: (result) => {
        const newItems = result.items;
        // Handle null or empty response
        if (!newItems || newItems.length === 0) {
          this.hasMore.set(false);
        } else {
          if (newItems.length < this.count) {
            this.hasMore.set(false);
          }
          this.items.update(current => [...current, ...newItems]);
          this.skip += this.count;
        }
        this.loading.set(false);
        this.isLoadingMore = false;
      },
      error: (err) => {
        this.error.set('Failed to load items');
        this.loading.set(false);
        this.isLoadingMore = false;
        console.error('Error loading items:', err);
      }
    });
  }

  @HostListener('window:scroll')
  onScroll(): void {
    if (this.scrollTimeout) clearTimeout(this.scrollTimeout);
    
    this.scrollTimeout = setTimeout(() => {
      const scrollPosition = window.innerHeight + window.scrollY;
      const bottomPosition = document.documentElement.scrollHeight - SCROLL_THRESHOLD_PX;

      if (scrollPosition >= bottomPosition && !this.loading() && this.hasMore() && !this.isLoadingMore) {
        this.loadItems();
      }
    }, SCROLL_DEBOUNCE_MS);
  }

  addToCart(itemID: number, event: Event): void {
    event.preventDefault();
    event.stopPropagation();
    this.cartService.addItem(itemID);
  }

  onItemHover(itemID: number): void {
    this.prefetchService.prefetchItem(itemID);
  }

  readonly skeletonSlots = Array.from({ length: 8 });
  readonly getDiscountedPrice = getDiscountedPrice;
  readonly getMainImage = getMainImage;
  readonly trackByItemId = trackByItemId;
  readonly getBadgeClass = getBadgeClass;

  private langService = inject(LanguageService);
  itemName(item: Item): string { return getTranslatedField(item, 'name', this.langService.currentLanguage()); }
}
