import { Component, TemplateRef, ViewChild, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { InfiniteScrollContainerComponent, InfiniteScrollEvent, InfiniteScrollConfig } from 'ui-essentials';

interface DemoItem {
  id: number;
  title: string;
  description: string;
  timestamp: Date;
  category: string;
}

@Component({
  selector: 'ui-infinite-scroll-container-demo',
  standalone: true,
  imports: [CommonModule, InfiniteScrollContainerComponent],
  template: `
    <div class="demo-container">
      <h2>Infinite Scroll Container Demo</h2>
      
      <!-- Basic Example -->
      <section class="demo-section">
        <h3>Basic Infinite Scroll (Content Projection)</h3>
        <div class="demo-showcase">
          <ui-infinite-scroll-container
            class="demo-scroll-container"
            [hasMore]="basicHasMore()"
            [loading]="basicLoading()"
            (loadMore)="loadMoreBasic($event)">
            
            @for (item of basicItems(); track item.id) {
              <div class="demo-item">
                <h4>{{ item.title }}</h4>
                <p>{{ item.description }}</p>
                <small>{{ item.timestamp | date:'short' }} - {{ item.category }}</small>
              </div>
            }
          </ui-infinite-scroll-container>
        </div>
      </section>

      <!-- Template-Based Example -->
      <section class="demo-section">
        <h3>Template-Based Rendering</h3>
        <div class="demo-showcase">
          <ui-infinite-scroll-container
            class="demo-scroll-container"
            [items]="templateItems()"
            [itemTemplate]="itemTemplate"
            [trackByFn]="trackByFn"
            [hasMore]="templateHasMore()"
            [loading]="templateLoading()"
            [config]="templateConfig"
            (loadMore)="loadMoreTemplate($event)">
          </ui-infinite-scroll-container>
          
          <ng-template #itemTemplate let-item="item" let-index="index" let-isLast="isLast">
            <div class="demo-template-item" [class.demo-template-item--last]="isLast">
              <div class="demo-template-item__header">
                <span class="demo-template-item__id">#{{ item.id }}</span>
                <span class="demo-template-item__category">{{ item.category }}</span>
              </div>
              <h4 class="demo-template-item__title">{{ item.title }}</h4>
              <p class="demo-template-item__description">{{ item.description }}</p>
              <div class="demo-template-item__footer">
                <small>Index: {{ index }} | {{ item.timestamp | date:'short' }}</small>
              </div>
            </div>
          </ng-template>
        </div>
      </section>

      <!-- Bidirectional Scrolling -->
      <section class="demo-section">
        <h3>Bidirectional Infinite Scroll</h3>
        <div class="demo-showcase">
          <ui-infinite-scroll-container
            class="demo-scroll-container"
            direction="both"
            [items]="bidirectionalItems()"
            [itemTemplate]="bidirectionalTemplate"
            [hasMore]="bidirectionalHasMore()"
            [loadingUp]="bidirectionalLoadingUp()"
            [loadingDown]="bidirectionalLoadingDown()"
            [config]="bidirectionalConfig"
            (loadMore)="loadMoreBidirectional($event)">
          </ui-infinite-scroll-container>
          
          <ng-template #bidirectionalTemplate let-item="item" let-index="index">
            <div class="demo-bidirectional-item">
              <div class="demo-bidirectional-item__content">
                <strong>Message {{ item.id }}</strong>
                <p>{{ item.description }}</p>
                <small>{{ item.timestamp | date:'short' }}</small>
              </div>
            </div>
          </ng-template>
        </div>
      </section>

      <!-- Custom Templates -->
      <section class="demo-section">
        <h3>Custom Loading & Error Templates</h3>
        <div class="demo-showcase">
          <ui-infinite-scroll-container
            class="demo-scroll-container"
            [items]="customItems()"
            [itemTemplate]="customItemTemplate"
            [loadingTemplate]="customLoadingTemplate"
            [errorTemplate]="customErrorTemplate"
            [endTemplate]="customEndTemplate"
            [hasMore]="customHasMore()"
            [loading]="customLoading()"
            [error]="customError()"
            [config]="customConfig"
            (loadMore)="loadMoreCustom($event)"
            (retryRequested)="retryCustom()">
          </ui-infinite-scroll-container>
          
          <ng-template #customItemTemplate let-item="item">
            <div class="demo-custom-item">
              <div class="demo-custom-item__avatar">
                {{ item.title.charAt(0) }}
              </div>
              <div class="demo-custom-item__content">
                <h4>{{ item.title }}</h4>
                <p>{{ item.description }}</p>
                <span class="demo-custom-item__time">{{ getTimeAgo(item.timestamp) }}</span>
              </div>
            </div>
          </ng-template>
          
          <ng-template #customLoadingTemplate>
            <div class="demo-custom-loading">
              <div class="demo-custom-loading__spinner"></div>
              <span>Loading amazing content...</span>
            </div>
          </ng-template>
          
          <ng-template #customErrorTemplate let-error="error">
            <div class="demo-custom-error">
              <div class="demo-custom-error__icon">⚠️</div>
              <h4>Oops! Something went wrong</h4>
              <p>{{ error }}</p>
            </div>
          </ng-template>
          
          <ng-template #customEndTemplate>
            <div class="demo-custom-end">
              <div class="demo-custom-end__icon">🎉</div>
              <h4>That's all folks!</h4>
              <p>You've reached the end of our amazing content.</p>
            </div>
          </ng-template>
        </div>
      </section>

      <!-- Configuration Examples -->
      <section class="demo-section">
        <h3>Configuration Options</h3>
        <div class="demo-controls">
          <div class="demo-control">
            <label>
              <input type="checkbox" [checked]="disableScroll()" (change)="toggleDisabled($event)">
              Disable Infinite Scroll
            </label>
          </div>
          <div class="demo-control">
            <label>
              Threshold: {{ threshold() }}px
              <input 
                type="range" 
                min="50" 
                max="500" 
                [value]="threshold()" 
                (input)="updateThreshold($event)">
            </label>
          </div>
          <div class="demo-control">
            <label>
              Debounce Time: {{ debounceTime() }}ms
              <input 
                type="range" 
                min="50" 
                max="1000" 
                [value]="debounceTime()" 
                (input)="updateDebounceTime($event)">
            </label>
          </div>
        </div>
        
        <div class="demo-showcase">
          <ui-infinite-scroll-container
            class="demo-scroll-container"
            [items]="configItems()"
            [itemTemplate]="configItemTemplate"
            [hasMore]="configHasMore()"
            [loading]="configLoading()"
            [config]="currentConfig()"
            (loadMore)="loadMoreConfig($event)">
          </ui-infinite-scroll-container>
          
          <ng-template #configItemTemplate let-item="item" let-index="index">
            <div class="demo-config-item">
              <span class="demo-config-item__index">{{ index + 1 }}</span>
              <div class="demo-config-item__content">
                <h4>{{ item.title }}</h4>
                <p>{{ item.description }}</p>
              </div>
            </div>
          </ng-template>
        </div>
      </section>

      <!-- API Methods Demo -->
      <section class="demo-section">
        <h3>API Methods</h3>
        <div class="demo-controls">
          <button type="button" (click)="scrollToTop()">Scroll to Top</button>
          <button type="button" (click)="scrollToBottom()">Scroll to Bottom</button>
          <button type="button" (click)="scrollToIndex(50)">Scroll to Item 50</button>
          <button type="button" (click)="resetApiScroll()">Reset Scroll</button>
        </div>
      </section>
    </div>
  `,
  styleUrl: './infinite-scroll-container-demo.component.scss'
})
export class InfiniteScrollContainerDemoComponent {
  @ViewChild('itemTemplate') itemTemplate!: TemplateRef<any>;
  
  // Basic example
  basicItems = signal<DemoItem[]>([]);
  basicLoading = signal(false);
  basicHasMore = signal(true);
  private basicPage = 1;

  // Template example
  templateItems = signal<DemoItem[]>([]);
  templateLoading = signal(false);
  templateHasMore = signal(true);
  private templatePage = 1;
  
  templateConfig: InfiniteScrollConfig = {
    threshold: 100,
    debounceTime: 150,
    itemHeight: 120
  };

  // Bidirectional example
  bidirectionalItems = signal<DemoItem[]>([]);
  bidirectionalLoadingUp = signal(false);
  bidirectionalLoadingDown = signal(false);
  bidirectionalHasMore = signal(true);
  private bidirectionalTopPage = 0;
  private bidirectionalBottomPage = 1;
  
  bidirectionalConfig: InfiniteScrollConfig = {
    threshold: 50,
    debounceTime: 200
  };

  // Custom templates example
  customItems = signal<DemoItem[]>([]);
  customLoading = signal(false);
  customHasMore = signal(true);
  customError = signal<string | undefined>(undefined);
  private customPage = 1;
  private customFailCount = 0;
  
  customConfig: InfiniteScrollConfig = {
    threshold: 150,
    debounceTime: 100
  };

  // Configuration example
  configItems = signal<DemoItem[]>([]);
  configLoading = signal(false);
  configHasMore = signal(true);
  private configPage = 1;

  // Configuration controls
  threshold = signal(200);
  debounceTime = signal(300);
  disableScroll = signal(false);

  currentConfig = signal<InfiniteScrollConfig>({
    threshold: 200,
    debounceTime: 300,
    disabled: false
  });

  constructor() {
    // Initialize with some data
    this.loadInitialData();
  }

  // Track by function for template rendering
  trackByFn = (index: number, item: DemoItem) => item.id;

  // Basic example methods
  loadMoreBasic(event: InfiniteScrollEvent): void {
    if (this.basicLoading()) return;

    this.basicLoading.set(true);
    
    // Simulate API call
    setTimeout(() => {
      const newItems = this.generateItems(this.basicPage * 20, 20, 'basic');
      this.basicItems.update(items => [...items, ...newItems]);
      this.basicPage++;
      this.basicLoading.set(false);
      
      // Stop loading after 5 pages
      if (this.basicPage > 5) {
        this.basicHasMore.set(false);
      }
    }, 1000);
  }

  // Template example methods
  loadMoreTemplate(event: InfiniteScrollEvent): void {
    if (this.templateLoading()) return;

    this.templateLoading.set(true);
    
    setTimeout(() => {
      const newItems = this.generateItems(this.templatePage * 15, 15, 'template');
      this.templateItems.update(items => [...items, ...newItems]);
      this.templatePage++;
      this.templateLoading.set(false);
      
      if (this.templatePage > 6) {
        this.templateHasMore.set(false);
      }
    }, 800);
  }

  // Bidirectional example methods
  loadMoreBidirectional(event: InfiniteScrollEvent): void {
    if (event.direction === 'down') {
      this.loadMoreBidirectionalDown();
    } else {
      this.loadMoreBidirectionalUp();
    }
  }

  private loadMoreBidirectionalDown(): void {
    if (this.bidirectionalLoadingDown()) return;

    this.bidirectionalLoadingDown.set(true);
    
    setTimeout(() => {
      const newItems = this.generateItems(this.bidirectionalBottomPage * 10, 10, 'chat');
      this.bidirectionalItems.update(items => [...items, ...newItems]);
      this.bidirectionalBottomPage++;
      this.bidirectionalLoadingDown.set(false);
    }, 600);
  }

  private loadMoreBidirectionalUp(): void {
    if (this.bidirectionalLoadingUp()) return;

    this.bidirectionalLoadingUp.set(true);
    
    setTimeout(() => {
      const startId = this.bidirectionalTopPage * 10;
      const newItems = this.generateItems(startId, 10, 'history');
      this.bidirectionalItems.update(items => [...newItems, ...items]);
      this.bidirectionalTopPage--;
      this.bidirectionalLoadingUp.set(false);
    }, 800);
  }

  // Custom templates example methods
  loadMoreCustom(event: InfiniteScrollEvent): void {
    if (this.customLoading()) return;

    this.customLoading.set(true);
    this.customError.set(undefined);
    
    // Simulate occasional failures
    const shouldFail = Math.random() < 0.3 && this.customFailCount < 2;
    
    setTimeout(() => {
      if (shouldFail) {
        this.customError.set('Network error: Failed to load more items');
        this.customLoading.set(false);
        this.customFailCount++;
      } else {
        const newItems = this.generateItems(this.customPage * 12, 12, 'custom');
        this.customItems.update(items => [...items, ...newItems]);
        this.customPage++;
        this.customLoading.set(false);
        
        if (this.customPage > 4) {
          this.customHasMore.set(false);
        }
      }
    }, 1200);
  }

  retryCustom(): void {
    this.loadMoreCustom({ direction: 'down', currentIndex: 0, scrollPosition: 0 });
  }

  // Configuration example methods
  loadMoreConfig(event: InfiniteScrollEvent): void {
    if (this.configLoading()) return;

    this.configLoading.set(true);
    
    setTimeout(() => {
      const newItems = this.generateItems(this.configPage * 10, 10, 'config');
      this.configItems.update(items => [...items, ...newItems]);
      this.configPage++;
      this.configLoading.set(false);
      
      if (this.configPage > 10) {
        this.configHasMore.set(false);
      }
    }, 500);
  }

  // Configuration controls
  toggleDisabled(event: Event): void {
    const disabled = (event.target as HTMLInputElement).checked;
    this.disableScroll.set(disabled);
    this.updateCurrentConfig();
  }

  updateThreshold(event: Event): void {
    const value = parseInt((event.target as HTMLInputElement).value);
    this.threshold.set(value);
    this.updateCurrentConfig();
  }

  updateDebounceTime(event: Event): void {
    const value = parseInt((event.target as HTMLInputElement).value);
    this.debounceTime.set(value);
    this.updateCurrentConfig();
  }

  private updateCurrentConfig(): void {
    this.currentConfig.set({
      threshold: this.threshold(),
      debounceTime: this.debounceTime(),
      disabled: this.disableScroll()
    });
  }

  // API methods - These would be called on component references
  scrollToTop(): void {
    console.log('Scroll to top - would call component method');
  }

  scrollToBottom(): void {
    console.log('Scroll to bottom - would call component method');
  }

  scrollToIndex(index: number): void {
    console.log(`Scroll to index ${index} - would call component method`);
  }

  resetApiScroll(): void {
    console.log('Reset scroll - would call component method');
  }

  // Utility methods
  getTimeAgo(date: Date): string {
    const now = new Date();
    const diff = now.getTime() - date.getTime();
    const minutes = Math.floor(diff / (1000 * 60));
    
    if (minutes < 1) return 'Just now';
    if (minutes < 60) return `${minutes}m ago`;
    if (minutes < 1440) return `${Math.floor(minutes / 60)}h ago`;
    return `${Math.floor(minutes / 1440)}d ago`;
  }

  private loadInitialData(): void {
    // Load initial data for all examples
    this.basicItems.set(this.generateItems(1, 20, 'basic'));
    this.templateItems.set(this.generateItems(1, 15, 'template'));
    this.bidirectionalItems.set(this.generateItems(1, 20, 'chat'));
    this.customItems.set(this.generateItems(1, 12, 'custom'));
    this.configItems.set(this.generateItems(1, 10, 'config'));
  }

  private generateItems(startId: number, count: number, type: string): DemoItem[] {
    const categories = ['Technology', 'Science', 'Arts', 'Sports', 'Travel', 'Food', 'Music', 'Literature'];
    
    return Array.from({ length: count }, (_, i) => ({
      id: startId + i,
      title: `${type.charAt(0).toUpperCase() + type.slice(1)} Item ${startId + i}`,
      description: `This is a sample description for ${type} item ${startId + i}. It contains some interesting content that demonstrates the infinite scroll functionality.`,
      timestamp: new Date(Date.now() - Math.random() * 86400000 * 30), // Random date within last 30 days
      category: categories[Math.floor(Math.random() * categories.length)]
    }));
  }
}