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

type TooltipPosition = 'top' | 'bottom' | 'left' | 'right';
type TooltipTrigger = 'hover' | 'click' | 'focus';
type TooltipSize = 'sm' | 'md' | 'lg';

@Component({
  selector: 'ui-tooltip',
  standalone: true,
  imports: [CommonModule],
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  template: `
    <div 
      class="ui-tooltip-wrapper"
      (mouseenter)="handleMouseEnter()"
      (mouseleave)="handleMouseLeave()"
      (click)="handleClick($event)"
      (focus)="handleFocus()"
      (blur)="handleBlur()">
      
      <!-- Trigger content -->
      <div class="ui-tooltip-trigger">
        <ng-content></ng-content>
      </div>
      
      <!-- Tooltip content -->
      @if (isVisible()) {
        <div 
          #tooltipElement
          class="ui-tooltip"
          [class.ui-tooltip--top]="position === 'top'"
          [class.ui-tooltip--bottom]="position === 'bottom'"
          [class.ui-tooltip--left]="position === 'left'"
          [class.ui-tooltip--right]="position === 'right'"
          [class.ui-tooltip--sm]="size === 'sm'"
          [class.ui-tooltip--md]="size === 'md'"
          [class.ui-tooltip--lg]="size === 'lg'"
          [attr.role]="'tooltip'"
          [attr.aria-hidden]="!isVisible()">
          
          <div class="ui-tooltip__content">
            {{ text }}
          </div>
          
          <div class="ui-tooltip__arrow"></div>
        </div>
      }
    </div>
  `,
  styleUrl: './tooltip.component.scss'
})
export class TooltipComponent implements OnDestroy {
  @ViewChild('tooltipElement') tooltipElement?: ElementRef;
  
  @Input() text = '';
  @Input() position: TooltipPosition = 'top';
  @Input() trigger: TooltipTrigger = 'hover';
  @Input() size: TooltipSize = 'md';
  @Input() disabled = false;
  @Input() delay = 500;
  
  @Output() tooltipShow = new EventEmitter<void>();
  @Output() tooltipHide = new EventEmitter<void>();
  
  protected isVisible = signal(false);
  private showTimeout?: number;
  private hideTimeout?: number;
  
  ngOnDestroy(): void {
    this.clearTimeouts();
  }
  
  handleMouseEnter(): void {
    if (this.trigger === 'hover' && !this.disabled) {
      this.scheduleShow();
    }
  }
  
  handleMouseLeave(): void {
    if (this.trigger === 'hover') {
      this.scheduleHide();
    }
  }
  
  handleClick(event: MouseEvent): void {
    if (this.trigger === 'click' && !this.disabled) {
      event.preventDefault();
      this.toggle();
    }
  }
  
  handleFocus(): void {
    if (this.trigger === 'focus' && !this.disabled) {
      this.show();
    }
  }
  
  handleBlur(): void {
    if (this.trigger === 'focus') {
      this.hide();
    }
  }
  
  private scheduleShow(): void {
    this.clearTimeouts();
    this.showTimeout = window.setTimeout(() => {
      this.show();
    }, this.delay);
  }
  
  private scheduleHide(): void {
    this.clearTimeouts();
    this.hideTimeout = window.setTimeout(() => {
      this.hide();
    }, 100);
  }
  
  private show(): void {
    if (!this.disabled && !this.isVisible()) {
      this.isVisible.set(true);
      this.tooltipShow.emit();
    }
  }
  
  private hide(): void {
    if (this.isVisible()) {
      this.isVisible.set(false);
      this.tooltipHide.emit();
    }
  }
  
  private toggle(): void {
    if (this.isVisible()) {
      this.hide();
    } else {
      this.show();
    }
  }
  
  private clearTimeouts(): void {
    if (this.showTimeout) {
      clearTimeout(this.showTimeout);
      this.showTimeout = undefined;
    }
    if (this.hideTimeout) {
      clearTimeout(this.hideTimeout);
      this.hideTimeout = undefined;
    }
  }
}