import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, ViewEncapsulation, ContentChild, AfterContentInit, OnDestroy } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AbstractControl, FormControl, NgControl, ValidationErrors } from '@angular/forms';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import { IconDefinition } from '@fortawesome/fontawesome-svg-core';
import { faExclamationCircle, faCheckCircle, faExclamationTriangle, faInfoCircle, faQuestionCircle } from '@fortawesome/free-solid-svg-icons';
import { Subject, takeUntil } from 'rxjs';

export type FormFieldSize = 'sm' | 'md' | 'lg';
export type FormFieldState = 'default' | 'error' | 'success' | 'warning' | 'info';
export type FormFieldLayout = 'vertical' | 'horizontal';

export interface ValidationMessage {
  type: string;
  message: string;
  icon?: IconDefinition;
}

@Component({
  selector: 'ui-form-field',
  standalone: true,
  imports: [CommonModule, FontAwesomeModule],
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  template: `
    <div class="ui-form-field" [class]="getWrapperClasses()">
      @if (layout === 'horizontal') {
        <!-- Horizontal Layout -->
        @if (label) {
          <label 
            class="ui-form-field__label"
            [class.ui-form-field__label--required]="required && !showOptional"
            [class.ui-form-field__label--optional]="showOptional && !required"
            [for]="fieldId"
          >
            {{ label }}
          </label>
        }
        
        <div class="ui-form-field__content">
          <div class="ui-form-field__control">
            <ng-content></ng-content>
          </div>
          
          <!-- Helper Text -->
          @if (helperText && !hasValidationMessages()) {
            <div class="ui-form-field__helper-text" [class]="getHelperTextClasses()">
              {{ helperText }}
            </div>
          }
          
          <!-- Validation Messages -->
          @if (hasValidationMessages()) {
            <div class="ui-form-field__validation" [class]="getValidationClasses()">
              <fa-icon 
                class="ui-form-field__validation-icon" 
                [icon]="getValidationIcon()"
              ></fa-icon>
              <div class="ui-form-field__validation-text">
                {{ getValidationMessage() }}
              </div>
            </div>
          }
          
          <!-- Character Counter -->
          @if (showCharacterCount && maxLength) {
            <div class="ui-form-field__char-counter" [class.ui-form-field__char-counter--over-limit]="isOverCharacterLimit()">
              {{ currentLength }}/{{ maxLength }}
            </div>
          }
          
          <!-- Hint Text -->
          @if (hintText) {
            <div class="ui-form-field__hint">
              <fa-icon class="ui-form-field__hint-icon" [icon]="faQuestionCircle"></fa-icon>
              {{ hintText }}
            </div>
          }
        </div>
      } @else {
        <!-- Vertical Layout -->
        @if (label) {
          <label 
            class="ui-form-field__label"
            [class.ui-form-field__label--required]="required && !showOptional"
            [class.ui-form-field__label--optional]="showOptional && !required"
            [for]="fieldId"
          >
            {{ label }}
          </label>
        }
        
        <div class="ui-form-field__control">
          <ng-content></ng-content>
        </div>
        
        <!-- Helper Text -->
        @if (helperText && !hasValidationMessages()) {
          <div class="ui-form-field__helper-text" [class]="getHelperTextClasses()">
            {{ helperText }}
          </div>
        }
        
        <!-- Validation Messages -->
        @if (hasValidationMessages()) {
          <div class="ui-form-field__validation" [class]="getValidationClasses()">
            <fa-icon 
              class="ui-form-field__validation-icon" 
              [icon]="getValidationIcon()"
            ></fa-icon>
            <div class="ui-form-field__validation-text">
              {{ getValidationMessage() }}
            </div>
          </div>
        }
        
        <!-- Character Counter -->
        @if (showCharacterCount && maxLength) {
          <div class="ui-form-field__char-counter" [class.ui-form-field__char-counter--over-limit]="isOverCharacterLimit()">
            {{ currentLength }}/{{ maxLength }}
          </div>
        }
        
        <!-- Hint Text -->
        @if (hintText) {
          <div class="ui-form-field__hint">
            <fa-icon class="ui-form-field__hint-icon" [icon]="faQuestionCircle"></fa-icon>
            {{ hintText }}
          </div>
        }
      }
    </div>
  `,
  styleUrl: './form-field.component.scss'
})
export class FormFieldComponent implements AfterContentInit, OnDestroy {
  @Input() label: string = '';
  @Input() size: FormFieldSize = 'md';
  @Input() state: FormFieldState = 'default';
  @Input() layout: FormFieldLayout = 'vertical';
  @Input() required = false;
  @Input() disabled = false;
  @Input() showOptional = false;
  @Input() helperText: string = '';
  @Input() hintText: string = '';
  @Input() errorMessage: string = '';
  @Input() successMessage: string = '';
  @Input() warningMessage: string = '';
  @Input() infoMessage: string = '';
  @Input() showCharacterCount = false;
  @Input() maxLength: number | null = null;
  @Input() currentLength = 0;
  @Input() fieldId: string = `form-field-${Math.random().toString(36).substr(2, 9)}`;
  @Input() validationMessages: { [key: string]: string } = {};
  @Input() customValidationMessages: ValidationMessage[] = [];
  @Input() compact = false;
  @Input() fullWidth = false;
  @Input() group = false;

  @Output() stateChange = new EventEmitter<FormFieldState>();
  @Output() validationChange = new EventEmitter<ValidationErrors | null>();

  @ContentChild(NgControl, { static: false }) ngControl: NgControl | null = null;

  // FontAwesome icons
  readonly faExclamationCircle = faExclamationCircle;
  readonly faCheckCircle = faCheckCircle;
  readonly faExclamationTriangle = faExclamationTriangle;
  readonly faInfoCircle = faInfoCircle;
  readonly faQuestionCircle = faQuestionCircle;

  private destroy$ = new Subject<void>();
  private currentState: FormFieldState = 'default';

  ngAfterContentInit(): void {
    if (this.ngControl && this.ngControl.control) {
      // Listen to control status changes
      this.ngControl.control.statusChanges
        .pipe(takeUntil(this.destroy$))
        .subscribe(() => {
          this.updateStateFromControl();
        });

      // Listen to value changes for character count
      this.ngControl.control.valueChanges
        .pipe(takeUntil(this.destroy$))
        .subscribe((value: string) => {
          this.currentLength = value ? value.length : 0;
        });

      // Initial state update
      this.updateStateFromControl();
    }
  }

  ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
  }

  getWrapperClasses(): string {
    const classes = [
      `ui-form-field--${this.size}`,
      `ui-form-field--${this.getCurrentState()}`,
      `ui-form-field--${this.layout}`
    ];

    if (this.disabled) classes.push('ui-form-field--disabled');
    if (this.compact) classes.push('ui-form-field--compact');
    if (this.fullWidth) classes.push('ui-form-field--full-width');
    if (this.group) classes.push('ui-form-field--group');

    return classes.join(' ');
  }

  getHelperTextClasses(): string {
    const state = this.getCurrentState();
    return `ui-form-field__helper-text--${state}`;
  }

  getValidationClasses(): string {
    const state = this.getCurrentState();
    return `ui-form-field__validation--${state}`;
  }

  getValidationIcon(): IconDefinition {
    const state = this.getCurrentState();
    switch (state) {
      case 'error':
        return this.faExclamationCircle;
      case 'success':
        return this.faCheckCircle;
      case 'warning':
        return this.faExclamationTriangle;
      case 'info':
        return this.faInfoCircle;
      default:
        return this.faExclamationCircle;
    }
  }

  getCurrentState(): FormFieldState {
    // Override state takes precedence
    if (this.state !== 'default') {
      return this.state;
    }

    // Check if we have a form control
    if (this.ngControl && this.ngControl.control) {
      const control = this.ngControl.control;
      
      // Error state
      if (control.invalid && (control.dirty || control.touched)) {
        return 'error';
      }
      
      // Success state
      if (control.valid && control.value && (control.dirty || control.touched)) {
        return 'success';
      }
    }

    // Check custom messages
    if (this.errorMessage) return 'error';
    if (this.successMessage) return 'success';
    if (this.warningMessage) return 'warning';
    if (this.infoMessage) return 'info';

    return 'default';
  }

  hasValidationMessages(): boolean {
    const currentState = this.getCurrentState();
    
    if (currentState === 'error') {
      return !!(this.getControlErrors() || this.errorMessage);
    }
    
    if (currentState === 'success') {
      return !!this.successMessage;
    }
    
    if (currentState === 'warning') {
      return !!this.warningMessage;
    }
    
    if (currentState === 'info') {
      return !!this.infoMessage;
    }

    return this.customValidationMessages.length > 0;
  }

  getValidationMessage(): string {
    const currentState = this.getCurrentState();
    
    if (currentState === 'error') {
      const controlErrors = this.getControlErrors();
      if (controlErrors) return controlErrors;
      return this.errorMessage || 'Please correct the error';
    }
    
    if (currentState === 'success') {
      return this.successMessage || 'Valid input';
    }
    
    if (currentState === 'warning') {
      return this.warningMessage || 'Warning message';
    }
    
    if (currentState === 'info') {
      return this.infoMessage || 'Information message';
    }

    if (this.customValidationMessages.length > 0) {
      return this.customValidationMessages[0].message;
    }

    return '';
  }

  isOverCharacterLimit(): boolean {
    return this.maxLength ? this.currentLength > this.maxLength : false;
  }

  private updateStateFromControl(): void {
    const newState = this.getCurrentState();
    if (newState !== this.currentState) {
      this.currentState = newState;
      this.stateChange.emit(newState);
    }

    if (this.ngControl && this.ngControl.control) {
      this.validationChange.emit(this.ngControl.control.errors);
    }
  }

  private getControlErrors(): string | null {
    if (!this.ngControl || !this.ngControl.control || !this.ngControl.control.errors) {
      return null;
    }

    const errors = this.ngControl.control.errors;
    const errorKey = Object.keys(errors)[0]; // Get first error

    // Check for custom validation messages first
    if (this.validationMessages[errorKey]) {
      return this.validationMessages[errorKey];
    }

    // Default error messages
    switch (errorKey) {
      case 'required':
        return 'This field is required';
      case 'email':
        return 'Please enter a valid email address';
      case 'minlength':
        return `Minimum length is ${errors[errorKey].requiredLength} characters`;
      case 'maxlength':
        return `Maximum length is ${errors[errorKey].requiredLength} characters`;
      case 'min':
        return `Minimum value is ${errors[errorKey].min}`;
      case 'max':
        return `Maximum value is ${errors[errorKey].max}`;
      case 'pattern':
        return 'Please enter a valid format';
      case 'url':
        return 'Please enter a valid URL';
      case 'number':
        return 'Please enter a valid number';
      case 'date':
        return 'Please enter a valid date';
      case 'time':
        return 'Please enter a valid time';
      case 'custom':
        return errors[errorKey].message || 'Invalid input';
      default:
        return 'Please correct this field';
    }
  }
}