import { Component, Input, ChangeDetectionStrategy, signal, computed, ViewChild, ElementRef } from '@angular/core';
import { CommonModule } from '@angular/common';

export type ProgressBarSize = 'sm' | 'md' | 'lg';
export type ProgressBarVariant = 'primary' | 'secondary' | 'success' | 'warning' | 'danger';
export type ProgressBarType = 'determinate' | 'indeterminate' | 'buffer';
export type ProgressBarState = 'default' | 'disabled';

@Component({
  selector: 'ui-progress-bar',
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [CommonModule],
  template: `
    <div class="progress-bar-wrapper" [class]="getWrapperClasses()" [attr.aria-label]="ariaLabel">
      
      @if (showLabelComputed()) {
        <div class="progress-bar__label" [class]="getLabelClasses()">
          <span class="progress-bar__label-text">{{ label }}</span>
          @if (showPercentageComputed() && type() === 'determinate') {
            <span class="progress-bar__percentage">{{ Math.round(value()) }}%</span>
          }
        </div>
      }
      
      <div 
        #progressElement
        class="progress-bar" 
        [class]="getProgressBarClasses()"
        role="progressbar"
        [attr.aria-valuenow]="type() === 'determinate' ? value() : null"
        [attr.aria-valuemin]="type() === 'determinate' ? 0 : null"
        [attr.aria-valuemax]="type() === 'determinate' ? 100 : null"
        [attr.aria-valuetext]="getAriaValueText()"
        [attr.aria-label]="ariaLabel || label || 'Progress'"
      >
        
        @if (type() === 'determinate') {
          <div 
            class="progress-bar__fill progress-bar__fill--determinate" 
            [class]="getFillClasses()"
            [style.width.%]="value()">
          </div>
        }
        
        @if (type() === 'indeterminate') {
          <div 
            class="progress-bar__fill progress-bar__fill--indeterminate" 
            [class]="getFillClasses()">
          </div>
        }
        
        @if (type() === 'buffer') {
          <div 
            class="progress-bar__buffer" 
            [class]="getBufferClasses()"
            [style.width.%]="bufferValue()">
          </div>
          <div 
            class="progress-bar__fill progress-bar__fill--buffer" 
            [class]="getFillClasses()"
            [style.width.%]="value()">
          </div>
        }
        
      </div>
      
      @if (helperTextComputed()) {
        <div class="progress-bar__helper-text" [class]="getHelperTextClasses()">
          {{ helperTextComputed() }}
        </div>
      }
      
    </div>
  `,
  styleUrls: ['./progress-bar.component.scss']
})
export class ProgressBarComponent {
  @ViewChild('progressElement', { static: false }) progressElement!: ElementRef<HTMLDivElement>;

  // Core inputs
  @Input() set progress(value: number) { this._value.set(Math.max(0, Math.min(100, value))); }
  @Input() set buffer(value: number) { this._bufferValue.set(Math.max(0, Math.min(100, value))); }
  @Input() label: string = '';
  @Input() size: ProgressBarSize = 'md';
  @Input() variant: ProgressBarVariant = 'primary';
  @Input() progressType: ProgressBarType = 'determinate';
  @Input() state: ProgressBarState = 'default';
  
  // Display options
  @Input() showLabel = true;
  @Input() showPercentage = true;
  @Input() striped = false;
  @Input() animated = false;
  
  // Accessibility
  @Input() ariaLabel: string = '';
  @Input() helperText: string = '';
  @Input() progressId: string = `progress-${Math.random().toString(36).substr(2, 9)}`;

  // Exposed Math for template
  protected readonly Math = Math;

  // Internal state
  private _value = signal<number>(0);
  private _bufferValue = signal<number>(0);

  // Computed properties
  protected value = computed(() => this._value());
  protected bufferValue = computed(() => this._bufferValue());
  protected type = computed(() => this.progressType);
  protected showLabelComputed = computed(() => this.label && this.showLabel);
  protected showPercentageComputed = computed(() => this.showPercentage && this.progressType === 'determinate');
  protected helperTextComputed = computed(() => this.helperText);

  ngOnInit(): void {
    // Initialize with default values if not set
    if (this._value() === 0 && this.progressType === 'determinate') {
      this._value.set(0);
    }
  }

  getAriaValueText(): string {
    if (this.progressType === 'determinate') {
      return `${Math.round(this.value())}% complete`;
    } else if (this.progressType === 'indeterminate') {
      return 'Loading...';
    } else {
      return `${Math.round(this.value())}% of ${Math.round(this.bufferValue())}%`;
    }
  }

  // CSS class getters
  getWrapperClasses(): string {
    const classes = [
      `progress-bar-wrapper--${this.size}`,
      `progress-bar-wrapper--${this.variant}`,
      `progress-bar-wrapper--${this.progressType}`,
      `progress-bar-wrapper--${this.state}`
    ];

    if (this.state === 'disabled') classes.push('progress-bar-wrapper--disabled');
    if (this.striped) classes.push('progress-bar-wrapper--striped');
    if (this.animated) classes.push('progress-bar-wrapper--animated');

    return classes.join(' ');
  }

  getProgressBarClasses(): string {
    const classes = [
      `progress-bar--${this.size}`,
      `progress-bar--${this.variant}`,
      `progress-bar--${this.progressType}`,
      `progress-bar--${this.state}`
    ];

    if (this.state === 'disabled') classes.push('progress-bar--disabled');

    return classes.join(' ');
  }

  getFillClasses(): string {
    const classes = [`progress-bar__fill--${this.size}`];
    
    if (this.striped) classes.push('progress-bar__fill--striped');
    if (this.animated) classes.push('progress-bar__fill--animated');
    if (this.state === 'disabled') classes.push('progress-bar__fill--disabled');
    
    return classes.join(' ');
  }

  getBufferClasses(): string {
    const classes = [`progress-bar__buffer--${this.size}`];
    
    if (this.state === 'disabled') classes.push('progress-bar__buffer--disabled');
    
    return classes.join(' ');
  }

  getLabelClasses(): string {
    const classes = [`progress-bar__label--${this.size}`];
    
    if (this.state === 'disabled') classes.push('progress-bar__label--disabled');
    
    return classes.join(' ');
  }

  getHelperTextClasses(): string {
    const classes = [`progress-bar__helper-text--${this.size}`];
    
    if (this.state === 'disabled') classes.push('progress-bar__helper-text--disabled');
    
    return classes.join(' ');
  }

  // Public methods for programmatic control
  setProgress(value: number): void {
    this._value.set(Math.max(0, Math.min(100, value)));
  }

  setBuffer(value: number): void {
    this._bufferValue.set(Math.max(0, Math.min(100, value)));
  }

  reset(): void {
    this._value.set(0);
    this._bufferValue.set(0);
  }

  complete(): void {
    this._value.set(100);
  }
}