import { Component, Input, Output, EventEmitter, OnInit, forwardRef, ElementRef, ViewChild } from "@angular/core";
import { CommonModule } from "@angular/common";
import {
  ReactiveFormsModule,
  FormControl,
  ControlValueAccessor,
  NG_VALUE_ACCESSOR
} from "@angular/forms";

export interface MultiSelectOption {
  value: any;
  label: string;
  disabled?: boolean;
}

@Component({
  selector: "app-multi-select",
  standalone: true,
  imports: [CommonModule, ReactiveFormsModule],
  templateUrl: "./multi-select.component.html",
  styleUrls: ["./multi-select.component.scss"],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => MultiSelectComponent),
      multi: true
    }
  ]
})
export class MultiSelectComponent implements OnInit, ControlValueAccessor {
  @Input() options: MultiSelectOption[] = [];
  @Input() placeholder: string = "Selecione...";
  @Input() label: string = "";
  @Input() disabled: boolean = false;
  @Input() required: boolean = false;
  @Input() maxSelections?: number;
  
  @Output() selectionChange = new EventEmitter<any[]>();

  @ViewChild('dropdown', { static: false }) dropdown!: ElementRef;

  selectedValues: any[] = [];
  isOpen = false;
  control = new FormControl();

  private onChange = (value: any[]) => {};
  private onTouched = () => {};

  constructor() {}

  ngOnInit() {
    // Configurar controle interno
    this.control.valueChanges.subscribe(value => {
      this.onChange(value || []);
      this.selectionChange.emit(value || []);
      this.onTouched();
    });
  }

  // ControlValueAccessor implementation
  writeValue(value: any[]): void {
    this.selectedValues = Array.isArray(value) ? [...value] : [];
    this.control.setValue(this.selectedValues, { emitEvent: false });
  }

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

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

  setDisabledState(isDisabled: boolean): void {
    this.disabled = isDisabled;
    if (isDisabled) {
      this.control.disable({ emitEvent: false });
    } else {
      this.control.enable({ emitEvent: false });
    }
  }

  // Component logic
  toggleDropdown() {
    if (!this.disabled) {
      this.isOpen = !this.isOpen;
      this.onTouched();
    }
  }

  closeDropdown() {
    this.isOpen = false;
  }

  onOptionClick(option: MultiSelectOption, event: Event) {
    event.stopPropagation();
    
    if (option.disabled) return;

    const currentValues = [...this.selectedValues];
    const index = currentValues.findIndex(val => val === option.value);

    if (index > -1) {
      // Remove se já está selecionado
      currentValues.splice(index, 1);
    } else {
      // Adiciona se não está selecionado e dentro do limite
      if (!this.maxSelections || currentValues.length < this.maxSelections) {
        currentValues.push(option.value);
      }
    }

    this.selectedValues = currentValues;
    this.control.setValue(this.selectedValues);
  }

  isSelected(option: MultiSelectOption): boolean {
    return this.selectedValues.includes(option.value);
  }

  getSelectedLabels(): string {
    if (this.selectedValues.length === 0) {
      return this.placeholder;
    }

    const labels = this.selectedValues
      .map(value => {
        const option = this.options.find(opt => opt.value === value);
        return option ? option.label : value;
      })
      .filter(Boolean);

    if (labels.length === 1) {
      return labels[0];
    } else if (labels.length <= 3) {
      return labels.join(', ');
    } else {
      return `${labels.length} selecionados`;
    }
  }

  clearAll() {
    this.selectedValues = [];
    this.control.setValue([]);
  }

  selectAll() {
    if (this.maxSelections && this.options.length > this.maxSelections) {
      return; // Não permite selecionar tudo se há limite
    }

    const availableOptions = this.options.filter(opt => !opt.disabled);
    this.selectedValues = availableOptions.map(opt => opt.value);
    this.control.setValue(this.selectedValues);
  }

  get hasSelections(): boolean {
    return this.selectedValues.length > 0;
  }

  get canSelectAll(): boolean {
    const availableOptions = this.options.filter(opt => !opt.disabled);
    return availableOptions.length > this.selectedValues.length && 
           (!this.maxSelections || availableOptions.length <= this.maxSelections);
  }

  trackByValue(index: number, option: MultiSelectOption): any {
    return option.value;
  }

  onFocus() {
    // Método para controle do foco (usado no label flutuante)
  }

  onBlur() {
    // Método para controle da perda de foco (usado no label flutuante)
    this.onTouched();
  }
} 