import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, ViewEncapsulation, signal, computed } from '@angular/core';
import { CommonModule } from '@angular/common';

export type CarouselSize = 'sm' | 'md' | 'lg';
export type CarouselVariant = 'card' | 'image' | 'content';
export type CarouselIndicatorStyle = 'dots' | 'bars' | 'thumbnails' | 'none';
export type CarouselTransition = 'slide' | 'fade' | 'scale';

export interface CarouselItem {
  id: string | number;
  imageUrl?: string;
  title?: string;
  subtitle?: string;
  content?: string;
  thumbnail?: string;
}

@Component({
  selector: 'ui-carousel',
  standalone: true,
  imports: [CommonModule],
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  template: `
    <div 
      class="ui-carousel"
      [class]="getComponentClasses()"
      [attr.aria-roledescription]="'carousel'"
      [attr.aria-label]="ariaLabel"
      role="region">
      
      <!-- Navigation buttons -->
      @if (showNavigation && items.length > 1) {
        <button 
          class="ui-carousel__nav ui-carousel__nav--prev"
          [disabled]="disabled || (currentIndex() === 0 && !loop)"
          (click)="goToPrevious()"
          [attr.aria-label]="'Previous slide'"
          type="button">
          <svg class="ui-carousel__nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <polyline points="15,18 9,12 15,6"></polyline>
          </svg>
        </button>
        
        <button 
          class="ui-carousel__nav ui-carousel__nav--next"
          [disabled]="disabled || (currentIndex() === items.length - 1 && !loop)"
          (click)="goToNext()"
          [attr.aria-label]="'Next slide'"
          type="button">
          <svg class="ui-carousel__nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <polyline points="9,18 15,12 9,6"></polyline>
          </svg>
        </button>
      }
      
      <!-- Carousel container -->
      <div class="ui-carousel__container">
        <div 
          class="ui-carousel__track"
          [style.transform]="transition === 'slide' ? 'translateX(-' + (currentIndex() * 100) + '%)' : 'translateX(0)'">
          @for (item of items; track item.id; let i = $index) {
            <div 
              class="ui-carousel__slide"
              [class.ui-carousel__slide--active]="i === currentIndex()"
              [attr.aria-hidden]="i === currentIndex() ? 'false' : 'true'"
              [attr.aria-label]="'Slide ' + (i + 1) + ' of ' + items.length">
              
              <!-- Content based on variant -->
              @switch (variant) {
                @case ('image') {
                  @if (item.imageUrl) {
                    <div class="ui-carousel__image-container">
                      <img 
                        [src]="item.imageUrl" 
                        [alt]="item.title || 'Carousel image'"
                        class="ui-carousel__image"
                        loading="lazy">
                      @if (item.title || item.subtitle) {
                        <div class="ui-carousel__image-overlay">
                          @if (item.title) {
                            <h3 class="ui-carousel__title">{{ item.title }}</h3>
                          }
                          @if (item.subtitle) {
                            <p class="ui-carousel__subtitle">{{ item.subtitle }}</p>
                          }
                        </div>
                      }
                    </div>
                  }
                }
                
                @case ('card') {
                  <div class="ui-carousel__card">
                    @if (item.imageUrl) {
                      <img 
                        [src]="item.imageUrl" 
                        [alt]="item.title || 'Card image'"
                        class="ui-carousel__card-image"
                        loading="lazy">
                    }
                    <div class="ui-carousel__card-content">
                      @if (item.title) {
                        <h3 class="ui-carousel__title">{{ item.title }}</h3>
                      }
                      @if (item.subtitle) {
                        <p class="ui-carousel__subtitle">{{ item.subtitle }}</p>
                      }
                      @if (item.content) {
                        <p class="ui-carousel__content">{{ item.content }}</p>
                      }
                    </div>
                  </div>
                }
                
                @case ('content') {
                  <div class="ui-carousel__content-slide">
                    @if (item.title) {
                      <h3 class="ui-carousel__title">{{ item.title }}</h3>
                    }
                    @if (item.subtitle) {
                      <p class="ui-carousel__subtitle">{{ item.subtitle }}</p>
                    }
                    @if (item.content) {
                      <div class="ui-carousel__content" [innerHTML]="item.content"></div>
                    }
                  </div>
                }
              }
            </div>
          }
        </div>
      </div>
      
      <!-- Indicators -->
      @if (showIndicators && indicatorStyle !== 'none' && items.length > 1) {
        <div class="ui-carousel__indicators" [class]="getIndicatorClasses()">
          @for (item of items; track item.id; let i = $index) {
            <button 
              class="ui-carousel__indicator"
              [class.ui-carousel__indicator--active]="i === currentIndex()"
              [disabled]="disabled"
              (click)="goToSlide(i)"
              [attr.aria-label]="'Go to slide ' + (i + 1)"
              type="button">
              @switch (indicatorStyle) {
                @case ('thumbnails') {
                  @if (item.thumbnail || item.imageUrl) {
                    <img 
                      [src]="item.thumbnail || item.imageUrl" 
                      [alt]="item.title || 'Slide thumbnail'"
                      class="ui-carousel__indicator-thumbnail">
                  }
                }
                @case ('dots') {
                  <span class="ui-carousel__indicator-dot"></span>
                }
                @case ('bars') {
                  <span class="ui-carousel__indicator-bar"></span>
                }
              }
            </button>
          }
        </div>
      }
    </div>
  `,
  styleUrl: './carousel.component.scss'
})
export class CarouselComponent {
  @Input() items: CarouselItem[] = [];
  @Input() size: CarouselSize = 'md';
  @Input() variant: CarouselVariant = 'image';
  @Input() transition: CarouselTransition = 'slide';
  @Input() indicatorStyle: CarouselIndicatorStyle = 'dots';
  @Input() disabled = false;
  @Input() autoplay = false;
  @Input() autoplayInterval = 3000;
  @Input() loop = true;
  @Input() showNavigation = true;
  @Input() showIndicators = true;
  @Input() ariaLabel = 'Image carousel';
  @Input() initialIndex = 0;

  @Output() slideChange = new EventEmitter<number>();
  @Output() itemClick = new EventEmitter<{item: CarouselItem, index: number}>();

  private _currentIndex = signal(this.initialIndex);
  private _autoplayTimer?: number;

  currentIndex = this._currentIndex.asReadonly();

  getComponentClasses(): string {
    const classes = [
      'ui-carousel',
      `ui-carousel--${this.size}`,
      `ui-carousel--${this.variant}`,
      `ui-carousel--${this.transition}`
    ];
    
    if (this.disabled) {
      classes.push('ui-carousel--disabled');
    }
    
    if (this.autoplay) {
      classes.push('ui-carousel--autoplay');
    }
    
    return classes.join(' ');
  }

  getIndicatorClasses(): string {
    const classes = ['ui-carousel__indicators'];
    
    if (this.indicatorStyle) {
      classes.push(`ui-carousel__indicators--${this.indicatorStyle}`);
    }
    
    return classes.join(' ');
  }

  ngOnInit(): void {
    this._currentIndex.set(this.initialIndex);
    if (this.autoplay && !this.disabled) {
      this.startAutoplay();
    }
  }

  ngOnDestroy(): void {
    this.stopAutoplay();
  }

  goToSlide(index: number): void {
    if (this.disabled || index < 0 || index >= this.items.length) {
      return;
    }

    this._currentIndex.set(index);
    this.slideChange.emit(index);
    this.resetAutoplay();
  }

  goToNext(): void {
    const nextIndex = this.loop && this.currentIndex() === this.items.length - 1 
      ? 0 
      : Math.min(this.currentIndex() + 1, this.items.length - 1);
    this.goToSlide(nextIndex);
  }

  goToPrevious(): void {
    const prevIndex = this.loop && this.currentIndex() === 0 
      ? this.items.length - 1 
      : Math.max(this.currentIndex() - 1, 0);
    this.goToSlide(prevIndex);
  }

  private startAutoplay(): void {
    this.stopAutoplay();
    this._autoplayTimer = window.setInterval(() => {
      this.goToNext();
    }, this.autoplayInterval);
  }

  private stopAutoplay(): void {
    if (this._autoplayTimer) {
      clearInterval(this._autoplayTimer);
      this._autoplayTimer = undefined;
    }
  }

  private resetAutoplay(): void {
    if (this.autoplay && !this.disabled) {
      this.stopAutoplay();
      this.startAutoplay();
    }
  }
}