import { Component, Input, forwardRef, OnInit, OnDestroy } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule, ControlValueAccessor, NG_VALUE_ACCESSOR, FormControl } from '@angular/forms';
import { Subject, takeUntil } from 'rxjs';
import { TabFormField } from '../../../interfaces/generic-tab-form.interface';

/**
 * 🔐 PasswordInputComponent - Componente de Input de Senha
 * 
 * Funcionalidades:
 * - Toggle de visibilidade (mostrar/ocultar senha)
 * - Indicador de força da senha (opcional)
 * - Suporte completo a validadores customizados
 * - Integração com FormControl do Angular
 * - Design responsivo e dark mode
 */

export interface PasswordStrengthConfig {
  showBar?: boolean;
  showText?: boolean;
  colors?: {
    weak: string;
    medium: string;
    strong: string;
  };
}

export interface PasswordInputField extends TabFormField {
  showStrengthIndicator?: boolean;
  allowToggleVisibility?: boolean;
  strengthConfig?: PasswordStrengthConfig;
}

interface PasswordStrength {
  score: number; // 0-4
  percentage: number; // 0-100
  text: string;
  class: string;
}

@Component({
  selector: 'app-password-input',
  standalone: true,
  imports: [CommonModule, ReactiveFormsModule],
  templateUrl: './password-input.component.html',
  styleUrl: './password-input.component.scss',
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => PasswordInputComponent),
      multi: true
    }
  ]
})
export class PasswordInputComponent implements ControlValueAccessor, OnInit, OnDestroy {
  @Input() field!: TabFormField;
  @Input() formControlName!: string;

  // Estados do componente
  isPasswordVisible = false;
  currentValue = '';
  isDisabled = false;
  isTouched = false;
  isFocused = false;

  // Força da senha
  passwordStrength: PasswordStrength = {
    score: 0,
    percentage: 0,
    text: 'Muito fraca',
    class: 'very-weak'
  };

  // Controle de lifecycle
  private destroy$ = new Subject<void>();

  // Callbacks do ControlValueAccessor
  private onChange = (value: any) => {};
  private onTouched = () => {};

  constructor() {}

  ngOnInit(): void {
    // Configurações padrão
    if (!this.field.allowToggleVisibility) {
      this.field.allowToggleVisibility = true;
    }
    if (!this.field.showStrengthIndicator) {
      this.field.showStrengthIndicator = false;
    }
  }

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

  // ========================================
  // 🎯 CONTROLE DE VISIBILIDADE
  // ========================================

  /**
   * Alterna a visibilidade da senha
   */
  togglePasswordVisibility(): void {
    if (this.field.allowToggleVisibility && !this.isDisabled) {
      this.isPasswordVisible = !this.isPasswordVisible;
    }
  }

  /**
   * Retorna o ícone apropriado para o botão de toggle
   */
  get toggleIcon(): string {
    return this.isPasswordVisible ? 'fas fa-eye-slash' : 'fas fa-eye';
  }

  /**
   * Retorna o tipo do input baseado na visibilidade
   */
  get inputType(): string {
    return this.isPasswordVisible ? 'text' : 'password';
  }

  // ========================================
  // 🎯 ANÁLISE DE FORÇA DA SENHA
  // ========================================

  /**
   * Analisa a força da senha e atualiza o indicador
   */
  private analyzePasswordStrength(password: string): void {
    if (!password) {
      this.passwordStrength = {
        score: 0,
        percentage: 0,
        text: 'Digite uma senha',
        class: 'empty'
      };
      return;
    }

    let score = 0;
    const checks = {
      length: password.length >= 8,
      lowercase: /[a-z]/.test(password),
      uppercase: /[A-Z]/.test(password),
      numbers: /\d/.test(password),
      symbols: /[@$!%*?&]/.test(password)
    };

    // Calcular pontuação
    if (checks.length) score++;
    if (checks.lowercase) score++;
    if (checks.uppercase) score++;
    if (checks.numbers) score++;
    if (checks.symbols) score++;

    // Bonus para senhas muito longas
    if (password.length >= 12) score += 0.5;
    if (password.length >= 16) score += 0.5;

    // Determinar força baseada na pontuação
    let text: string;
    let className: string;
    let percentage: number;

    if (score < 2) {
      text = 'Muito fraca';
      className = 'very-weak';
      percentage = 20;
    } else if (score < 3) {
      text = 'Fraca';
      className = 'weak';
      percentage = 40;
    } else if (score < 4) {
      text = 'Média';
      className = 'medium';
      percentage = 60;
    } else if (score < 5) {
      text = 'Forte';
      className = 'strong';
      percentage = 80;
    } else {
      text = 'Muito forte';
      className = 'very-strong';
      percentage = 100;
    }

    this.passwordStrength = {
      score: Math.floor(score),
      percentage,
      text,
      class: className
    };
  }

  // ========================================
  // 🎯 EVENTOS DE INPUT
  // ========================================

  /**
   * Manipula mudanças no input
   */
  onInput(event: Event): void {
    const target = event.target as HTMLInputElement;
    const value = target.value;
    
    this.currentValue = value;
    this.onChange(value);
    
    // Analisar força da senha se habilitado
    if (this.field.showStrengthIndicator) {
      this.analyzePasswordStrength(value);
    }
  }

  /**
   * Manipula evento de blur (perda de foco)
   */
  onBlur(): void {
    this.isFocused = false;
    this.isTouched = true;
    this.onTouched();
  }

  /**
   * Manipula evento de focus
   */
  onFocus(): void {
    this.isFocused = true;
  }

  // ========================================
  // 🎯 CONTROLE VALUE ACCESSOR
  // ========================================

  writeValue(value: any): void {
    this.currentValue = value || '';
    if (this.field?.showStrengthIndicator) {
      this.analyzePasswordStrength(this.currentValue);
    }
  }

  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

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

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

  // ========================================
  // 🎯 HELPERS E GETTERS
  // ========================================

  /**
   * Verifica se deve mostrar o indicador de força
   */
  get shouldShowStrengthIndicator(): boolean {
    return !!(this.field?.showStrengthIndicator && (this.currentValue || this.isFocused));
  }

  /**
   * Verifica se deve mostrar o botão de toggle
   */
  get shouldShowToggleButton(): boolean {
    return !!(this.field?.allowToggleVisibility && this.currentValue);
  }

  /**
   * Retorna as classes CSS para o container
   */
  get containerClasses(): string {
    const classes = ['password-input-container'];
    
    if (this.isFocused) classes.push('focused');
    if (this.isTouched) classes.push('touched');
    if (this.isDisabled) classes.push('disabled');
    if (this.currentValue) classes.push('has-value');
    
    return classes.join(' ');
  }

  /**
   * Retorna as classes CSS para o input
   */
  get inputClasses(): string {
    const classes = ['password-input'];
    
    if (this.field?.required) classes.push('required');
    if (this.shouldShowToggleButton) classes.push('with-toggle');
    
    return classes.join(' ');
  }

  /**
   * Retorna o placeholder do campo
   */
  get placeholder(): string {
    return this.field?.placeholder || 'Digite a senha';
  }

  /**
   * Retorna o label do campo
   */
  get label(): string {
    return this.field?.label || 'Senha';
  }

  /**
   * Verifica se o campo é obrigatório
   */
  get isRequired(): boolean {
    return !!this.field?.required;
  }

  // ========================================
  // 🎯 MÉTODOS PARA VALIDAÇÃO DE REQUISITOS
  // ========================================

  /**
   * Verifica se a senha tem pelo menos 8 caracteres
   */
  hasMinLength(): boolean {
    return this.currentValue.length >= 8;
  }

  /**
   * Verifica se a senha tem letra minúscula
   */
  hasLowercase(): boolean {
    return /[a-z]/.test(this.currentValue);
  }

  /**
   * Verifica se a senha tem letra maiúscula
   */
  hasUppercase(): boolean {
    return /[A-Z]/.test(this.currentValue);
  }

  /**
   * Verifica se a senha tem número
   */
  hasNumber(): boolean {
    return /\d/.test(this.currentValue);
  }

  /**
   * Verifica se a senha tem caractere especial
   */
  hasSpecialChar(): boolean {
    return /[@$!%*?&]/.test(this.currentValue);
  }

  /**
   * Retorna o ícone para um requisito
   */
  getRequirementIcon(isMet: boolean): string {
    return isMet ? 'fas fa-check' : 'fas fa-times';
  }
}
