import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, forwardRef, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { IconDefinition } from '@fortawesome/fontawesome-svg-core';
import { faTimes, faSpinner } from '@fortawesome/free-solid-svg-icons';

export type TextareaSize = 'sm' | 'md' | 'lg';
export type TextareaVariant = 'outlined' | 'filled' | 'underlined';
export type TextareaState = 'default' | 'error' | 'success' | 'warning';
export type TextareaResize = 'none' | 'vertical' | 'horizontal' | 'both';

@Component({
  selector: 'ui-textarea',
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [CommonModule, FontAwesomeModule],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => TextareaComponent),
      multi: true
    }
  ],
  template: `
    <div class="textarea-wrapper" [class]="getWrapperClasses()">
      <!-- Label -->
      @if (label) {
        <label 
          class="textarea__label"
          [for]="textareaId"
          [class.textarea__label--required]="required"
        >
          {{ label }}
          @if (required) {
            <span class="textarea__required-indicator">*</span>
          }
        </label>
      }
      
      <!-- Textarea Container -->
      <div class="textarea__container" [class]="getContainerClasses()">
        <!-- Prefix Icon -->
        @if (prefixIcon) {
          <div class="textarea__prefix-icon">
            <fa-icon [icon]="prefixIcon"></fa-icon>
          </div>
        }
        
        <!-- Textarea Field -->
        <textarea
          [id]="textareaId"
          class="textarea__field"
          [placeholder]="placeholder"
          [disabled]="disabled"
          [readonly]="readonly"
          [required]="required"
          [rows]="rows"
          [cols]="cols"
          [attr.maxlength]="maxLength"
          [value]="value"
          (input)="onInput($event)"
          (focus)="onFocus($event)"
          (blur)="onBlur($event)"
          (keydown)="onKeyDown($event)"
        ></textarea>
        
        <!-- Suffix Content -->
        <div class="textarea__suffix" [class.textarea__suffix--has-content]="hasSuffixContent()">
          <!-- Clear Button -->
          @if (clearable && value && !disabled) {
            <button
              type="button"
              class="textarea__clear-btn"
              (click)="clearValue()"
              [attr.aria-label]="'Clear ' + (label || 'textarea')"
            >
              <fa-icon [icon]="faTimes"></fa-icon>
            </button>
          }
          
          <!-- Loading Spinner -->
          @if (loading) {
            <div class="textarea__spinner">
              <fa-icon [icon]="faSpinner" [animation]="'spin'"></fa-icon>
            </div>
          }
          
          <!-- Custom Suffix -->
          @if (suffixIcon) {
            <div class="textarea__suffix-icon">
              <fa-icon [icon]="suffixIcon"></fa-icon>
            </div>
          }
        </div>
      </div>
      
      <!-- Helper Text / Error Message -->
      @if (helperText || errorMessage) {
        <div class="textarea__helper-text" [class]="getHelperTextClasses()">
          {{ state === 'error' ? errorMessage : helperText }}
        </div>
      }
      
      <!-- Character Counter -->
      @if (maxLength && showCharacterCount) {
        <div class="textarea__char-counter">
          {{ value.length }}/{{ maxLength }}
        </div>
      }
    </div>
  `,
  styleUrls: ['./textarea.component.scss']
})
export class TextareaComponent implements ControlValueAccessor {
  @Input() label: string = '';
  @Input() placeholder: string = '';
  @Input() size: TextareaSize = 'md';
  @Input() variant: TextareaVariant = 'outlined';
  @Input() state: TextareaState = 'default';
  @Input() disabled = false;
  @Input() readonly = false;
  @Input() required = false;
  @Input() loading = false;
  @Input() clearable = false;
  @Input() prefixIcon: IconDefinition | null = null;
  @Input() suffixIcon: IconDefinition | null = null;
  @Input() helperText: string = '';
  @Input() errorMessage: string = '';
  @Input() maxLength: number | null = null;
  @Input() showCharacterCount = false;
  @Input() rows: number = 4;
  @Input() cols: number | null = null;
  @Input() resize: TextareaResize = 'vertical';
  @Input() autoResize = false;
  @Input() textareaId: string = `textarea-${Math.random().toString(36).substr(2, 9)}`;

  @Output() textareaChange = new EventEmitter<string>();
  @Output() textareaFocus = new EventEmitter<FocusEvent>();
  @Output() textareaBlur = new EventEmitter<FocusEvent>();
  @Output() keyDown = new EventEmitter<KeyboardEvent>();
  @Output() clear = new EventEmitter<void>();

  value = '';
  focused = false;

  // FontAwesome icons
  readonly faTimes = faTimes;
  readonly faSpinner = faSpinner;

  // ControlValueAccessor implementation
  private onChange = (value: string) => {};
  private onTouched = () => {};

  writeValue(value: string): void {
    this.value = value || '';
  }

  registerOnChange(fn: (value: string) => void): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: () => void): void {
    this.onTouched = fn;
  }

  setDisabledState(isDisabled: boolean): void {
    this.disabled = isDisabled;
  }

  getWrapperClasses(): string {
    const classes = [
      `textarea-wrapper--${this.size}`,
      `textarea-wrapper--${this.variant}`,
      `textarea-wrapper--${this.state}`,
      `textarea-wrapper--resize-${this.resize}`
    ];

    if (this.disabled) classes.push('textarea-wrapper--disabled');
    if (this.focused) classes.push('textarea-wrapper--focused');
    if (this.readonly) classes.push('textarea-wrapper--readonly');
    if (this.loading) classes.push('textarea-wrapper--loading');
    if (this.autoResize) classes.push('textarea-wrapper--auto-resize');

    return classes.join(' ');
  }

  getContainerClasses(): string {
    const classes: string[] = [];

    if (this.prefixIcon) classes.push('textarea__container--has-prefix');
    if (this.hasSuffixContent()) classes.push('textarea__container--has-suffix');

    return classes.join(' ');
  }

  getHelperTextClasses(): string {
    const classes = [`textarea__helper-text--${this.state}`];
    return classes.join(' ');
  }

  hasSuffixContent(): boolean {
    return !!(
      this.clearable ||
      this.loading ||
      this.suffixIcon
    );
  }

  onInput(event: Event): void {
    const target = event.target as HTMLTextAreaElement;
    this.value = target.value;
    
    if (this.autoResize) {
      this.adjustHeight(target);
    }
    
    this.onChange(this.value);
    this.textareaChange.emit(this.value);
  }

  onFocus(event: FocusEvent): void {
    this.focused = true;
    this.textareaFocus.emit(event);
  }

  onBlur(event: FocusEvent): void {
    this.focused = false;
    this.onTouched();
    this.textareaBlur.emit(event);
  }

  onKeyDown(event: KeyboardEvent): void {
    this.keyDown.emit(event);
  }

  clearValue(): void {
    this.value = '';
    this.onChange(this.value);
    this.textareaChange.emit(this.value);
    this.clear.emit();
  }

  private adjustHeight(textarea: HTMLTextAreaElement): void {
    textarea.style.height = 'auto';
    textarea.style.height = textarea.scrollHeight + 'px';
  }
}