import { Component, Input, Output, EventEmitter, forwardRef } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ControlValueAccessor, NG_VALUE_ACCESSOR, ReactiveFormsModule, FormsModule } from '@angular/forms';

import { CustomInputComponent } from '../../inputs/custom-input/custom-input.component';

export interface DateRange {
  start?: string;
  end?: string;
}

/**
 * 🗓️ DateRangeFilterComponent - Componente padronizado para filtros de período
 * 
 * ✨ Funcionalidades:
 * - Padronização automática com date_start e date_end
 * - Integração com ControlValueAccessor
 * - Validação de datas
 * - Formatação automática para API
 * 
 * 🎯 Uso:
 * <app-date-range-filter 
 *   [label]="'Período'"
 *   [startPlaceholder]="'Data inicial'"
 *   [endPlaceholder]="'Data final'"
 *   [(ngModel)]="dateRange">
 * </app-date-range-filter>
 */
@Component({
  selector: 'app-date-range-filter',
  standalone: true,
  imports: [
    CommonModule,
    ReactiveFormsModule,
    FormsModule
  ],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => DateRangeFilterComponent),
      multi: true
    }
  ],
  templateUrl: './date-range-filter.component.html',
  styleUrl: './date-range-filter.component.scss'
})
export class DateRangeFilterComponent implements ControlValueAccessor {
  @Input() label: string = 'Período';
  @Input() startPlaceholder: string = 'Data inicial';
  @Input() endPlaceholder: string = 'Data final';
  @Input() required: boolean = false;
  @Input() disabled: boolean = false;

  @Output() rangeChanged = new EventEmitter<DateRange>();

  // Internal model
  internalValue: DateRange = {};

  // ControlValueAccessor
  private onChange = (value: DateRange) => {};
  onTouched = () => {}; // Public para template

  get startDate(): string {
    return this.internalValue.start || '';
  }

  set startDate(value: string) {
    this.internalValue.start = value;
    this.notifyChanges();
  }

  get endDate(): string {
    return this.internalValue.end || '';
  }

  set endDate(value: string) {
    this.internalValue.end = value;
    this.notifyChanges();
  }

  private notifyChanges() {
    this.onChange(this.internalValue);
    this.rangeChanged.emit(this.internalValue);
  }

  // ControlValueAccessor implementation
  writeValue(value: DateRange | null): void {
    if (value) {
      this.internalValue = { ...value };
    } else {
      this.internalValue = {};
    }
  }

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

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

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

  /**
   * 🎯 Converte para formato da API (date_start, date_end)
   */
  toApiFormat(): { date_start?: string; date_end?: string } {
    const result: { date_start?: string; date_end?: string } = {};
    
    if (this.internalValue.start) {
      result.date_start = this.formatDateForApi(this.internalValue.start);
    }
    
    if (this.internalValue.end) {
      result.date_end = this.formatDateForApi(this.internalValue.end);
    }
    
    return result;
  }

  /**
   * 🗓️ Formatar data para API (YYYY-MM-DD)
   */
  private formatDateForApi(date: string): string {
    if (!date) return '';
    
    // Se já está no formato correto
    if (/^\d{4}-\d{2}-\d{2}$/.test(date)) {
      return date;
    }
    
    // Converter de outros formatos
    const dateObj = new Date(date);
    if (isNaN(dateObj.getTime())) {
      return date; // Retorna original se não conseguir converter
    }
    
    return dateObj.toISOString().split('T')[0];
  }

  /**
   * ✅ Validar se o range é válido
   */
  isValidRange(): boolean {
    if (!this.internalValue.start || !this.internalValue.end) {
      return true; // Válido se apenas um estiver preenchido
    }
    
    const startDate = new Date(this.internalValue.start);
    const endDate = new Date(this.internalValue.end);
    
    return startDate <= endDate;
  }

  /**
   * 🧹 Limpar filtros
   */
  clear(): void {
    this.internalValue = {};
    this.notifyChanges();
  }

  /**
   * ❓ Verificar se tem valores
   */
  hasValue(): boolean {
    return !!(this.internalValue.start || this.internalValue.end);
  }
} 