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

export type SkeletonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
export type SkeletonShape = 'text' | 'heading' | 'avatar' | 'card' | 'button' | 'image' | 'circle' | 'rounded' | 'square';
export type SkeletonAnimation = 'shimmer' | 'pulse' | 'wave';
export type SkeletonWidth = 'w-25' | 'w-50' | 'w-75' | 'w-full' | 'auto';

@Component({
  selector: 'ui-skeleton-loader',
  standalone: true,
  imports: [CommonModule],
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  template: `
    <div 
      class="ui-skeleton-loader"
      [class]="skeletonClasses"
      [style.width]="customWidth"
      [style.height]="customHeight"
      [attr.aria-label]="ariaLabel"
      [attr.aria-busy]="loading"
      [attr.role]="role"
      [attr.data-testid]="'skeleton-' + shape + '-' + size">
    </div>
  `,
  styleUrl: './skeleton-loader.component.scss'
})
export class SkeletonLoaderComponent {
  @Input() size: SkeletonSize = 'md';
  @Input() shape: SkeletonShape = 'text';
  @Input() animation: SkeletonAnimation = 'shimmer';
  @Input() width: SkeletonWidth = 'w-full';
  @Input() loading = true;
  @Input() customWidth?: string;
  @Input() customHeight?: string;
  @Input() rounded = false;
  @Input() circle = false;
  @Input() ariaLabel = 'Loading content';
  @Input() role = 'status';
  @Input() class = '';

  get skeletonClasses(): string {
    const classes = [
      'ui-skeleton-loader',
      `ui-skeleton-loader--${this.size}`,
      `ui-skeleton-loader--${this.shape}`,
      `ui-skeleton-loader--${this.animation}`,
      this.width !== 'auto' ? `ui-skeleton-loader--${this.width}` : '',
      this.loading ? 'ui-skeleton-loader--loading' : 'ui-skeleton-loader--loaded',
      this.rounded ? 'ui-skeleton-loader--rounded' : '',
      this.circle ? 'ui-skeleton-loader--circle' : '',
      this.class
    ].filter(Boolean);

    return classes.join(' ');
  }
}

@Component({
  selector: 'ui-skeleton-group',
  standalone: true,
  imports: [CommonModule],
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  template: `
    <div 
      class="ui-skeleton-group"
      [class]="groupClasses"
      [attr.aria-label]="ariaLabel"
      [attr.role]="role">
      <ng-content></ng-content>
    </div>
  `,
  styleUrl: './skeleton-loader.component.scss'
})
export class SkeletonGroupComponent {
  @Input() variant: 'vertical' | 'horizontal' | 'grid' | 'avatar-text' | 'card' | 'table' = 'vertical';
  @Input() ariaLabel = 'Loading multiple items';
  @Input() role = 'status';
  @Input() class = '';

  get groupClasses(): string {
    const classes = [
      'ui-skeleton-group',
      this.variant !== 'vertical' ? `ui-skeleton-group--${this.variant}` : '',
      this.class
    ].filter(Boolean);

    return classes.join(' ');
  }
}

// Pre-built skeleton patterns for common use cases
@Component({
  selector: 'ui-skeleton-text-block',
  standalone: true,
  imports: [CommonModule, SkeletonLoaderComponent, SkeletonGroupComponent],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <ui-skeleton-group>
      @for (line of lineArray; track $index) {
        <ui-skeleton-loader 
          shape="text"
          [size]="size"
          [width]="getLineWidth($index)"
          [animation]="animation">
        </ui-skeleton-loader>
      }
    </ui-skeleton-group>
  `
})
export class SkeletonTextBlockComponent {
  @Input() lines = 3;
  @Input() size: SkeletonSize = 'md';
  @Input() animation: SkeletonAnimation = 'shimmer';
  @Input() lastLineWidth: SkeletonWidth = 'w-75';

  get lineArray(): number[] {
    return Array.from({ length: this.lines }, (_, i) => i);
  }

  getLineWidth(index: number): SkeletonWidth {
    return index === this.lines - 1 ? this.lastLineWidth : 'w-full';
  }
}

@Component({
  selector: 'ui-skeleton-article',
  standalone: true,
  imports: [CommonModule, SkeletonLoaderComponent, SkeletonGroupComponent],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <ui-skeleton-group>
      <!-- Article title -->
      <ui-skeleton-loader 
        shape="heading"
        size="lg"
        width="w-75"
        [animation]="animation">
      </ui-skeleton-loader>
      
      <!-- Article meta -->
      <ui-skeleton-loader 
        shape="text"
        size="sm"
        width="w-50"
        [animation]="animation">
      </ui-skeleton-loader>
      
      <!-- Article image -->
      @if (showImage) {
        <ui-skeleton-loader 
          shape="image"
          [animation]="animation">
        </ui-skeleton-loader>
      }
      
      <!-- Article content -->
      @for (line of contentArray; track $index) {
        <ui-skeleton-loader 
          shape="text"
          [width]="getContentLineWidth($index)"
          [animation]="animation">
        </ui-skeleton-loader>
      }
    </ui-skeleton-group>
  `
})
export class SkeletonArticleComponent {
  @Input() showImage = true;
  @Input() contentLines = 5;
  @Input() animation: SkeletonAnimation = 'shimmer';

  get contentArray(): number[] {
    return Array.from({ length: this.contentLines }, (_, i) => i);
  }

  getContentLineWidth(index: number): SkeletonWidth {
    if (index === this.contentLines - 1) return 'w-50';
    if (index === this.contentLines - 2) return 'w-75';
    return 'w-full';
  }
}

@Component({
  selector: 'ui-skeleton-card',
  standalone: true,
  imports: [CommonModule, SkeletonLoaderComponent, SkeletonGroupComponent],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <ui-skeleton-group variant="card">
      <!-- Card image -->
      @if (showImage) {
        <ui-skeleton-loader 
          shape="image"
          [animation]="animation">
        </ui-skeleton-loader>
      }
      
      <!-- Card title -->
      <ui-skeleton-loader 
        shape="heading"
        size="md"
        width="w-75"
        [animation]="animation">
      </ui-skeleton-loader>
      
      <!-- Card content -->
      @for (line of contentArray; track $index) {
        <ui-skeleton-loader 
          shape="text"
          [width]="getCardLineWidth($index)"
          [animation]="animation">
        </ui-skeleton-loader>
      }
      
      <!-- Card actions -->
      @if (showActions) {
        <ui-skeleton-group variant="horizontal">
          <ui-skeleton-loader 
            shape="button"
            size="sm"
            width="auto"
            customWidth="80px"
            [animation]="animation">
          </ui-skeleton-loader>
          <ui-skeleton-loader 
            shape="button"
            size="sm"
            width="auto"
            customWidth="80px"
            [animation]="animation">
          </ui-skeleton-loader>
        </ui-skeleton-group>
      }
    </ui-skeleton-group>
  `
})
export class SkeletonCardComponent {
  @Input() showImage = true;
  @Input() showActions = true;
  @Input() contentLines = 3;
  @Input() animation: SkeletonAnimation = 'shimmer';

  get contentArray(): number[] {
    return Array.from({ length: this.contentLines }, (_, i) => i);
  }

  getCardLineWidth(index: number): SkeletonWidth {
    if (index === this.contentLines - 1) return 'w-50';
    return 'w-full';
  }
}

@Component({
  selector: 'ui-skeleton-profile',
  standalone: true,
  imports: [CommonModule, SkeletonLoaderComponent, SkeletonGroupComponent],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <ui-skeleton-group variant="avatar-text">
      <!-- Profile avatar -->
      <ui-skeleton-loader 
        shape="avatar"
        [size]="avatarSize"
        [animation]="animation">
      </ui-skeleton-loader>
      
      <!-- Profile info -->
      <div class="ui-skeleton-content">
        <!-- Name -->
        <ui-skeleton-loader 
          shape="text"
          size="lg"
          width="w-50"
          [animation]="animation">
        </ui-skeleton-loader>
        
        <!-- Role/Title -->
        <ui-skeleton-loader 
          shape="text"
          size="sm"
          width="w-75"
          [animation]="animation">
        </ui-skeleton-loader>
        
        <!-- Additional info -->
        @if (showExtraInfo) {
          <ui-skeleton-loader 
            shape="text"
            size="sm"
            width="w-25"
            [animation]="animation">
          </ui-skeleton-loader>
        }
      </div>
    </ui-skeleton-group>
  `
})
export class SkeletonProfileComponent {
  @Input() avatarSize: SkeletonSize = 'lg';
  @Input() showExtraInfo = true;
  @Input() animation: SkeletonAnimation = 'shimmer';
}

@Component({
  selector: 'ui-skeleton-table-row',
  standalone: true,
  imports: [CommonModule, SkeletonLoaderComponent, SkeletonGroupComponent],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <ui-skeleton-group variant="table">
      @for (column of columnArray; track $index) {
        <ui-skeleton-loader 
          shape="text"
          [width]="getColumnWidth($index)"
          [animation]="animation">
        </ui-skeleton-loader>
      }
    </ui-skeleton-group>
  `
})
export class SkeletonTableRowComponent {
  @Input() columns = 3;
  @Input() animation: SkeletonAnimation = 'shimmer';

  get columnArray(): number[] {
    return Array.from({ length: this.columns }, (_, i) => i);
  }

  getColumnWidth(index: number): SkeletonWidth {
    const widths: SkeletonWidth[] = ['w-25', 'w-50', 'w-25', 'w-full'];
    return widths[index % widths.length];
  }
}

// Convenience export for all skeleton components
export const SKELETON_COMPONENTS = [
  SkeletonLoaderComponent,
  SkeletonGroupComponent,
  SkeletonTextBlockComponent,
  SkeletonArticleComponent,
  SkeletonCardComponent,
  SkeletonProfileComponent,
  SkeletonTableRowComponent
] as const;