import {
  Component,
  Input,
  Output,
  EventEmitter,
  forwardRef,
  ViewChild,
  ElementRef,
  OnInit,
} from '@angular/core';

import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';

@Component({
  selector: 'ccl-datefield',
  standalone: true,
  imports: [],
  templateUrl: './date-field.html',
  styleUrls: ['./date-field.css'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => DateFieldComponent),
      multi: true,
    },
  ],
})
export class DateFieldComponent implements ControlValueAccessor, OnInit {
  @Input() value: Date | null = null;
  @Input() minDate?: Date;
  @Input() maxDate?: Date;
  @Input() disabled = false;
  @Input() required = false;
  @Input() showTime = false;

  @Output() onChange = new EventEmitter<Date | null>();

  @ViewChild('inputEl') inputEl!: ElementRef<HTMLInputElement>;

  errorMessage = '';

  onTouched: () => void = () => {};
  private onChangeFn: (val: Date | null) => void = () => {};

  ngOnInit() {
    // Initialize component
  }

  writeValue(value: Date | null): void {
    this.value = value;
  }

  registerOnChange(fn: (val: Date | null) => void): void {
    this.onChangeFn = fn;
  }

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

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

  getInputValue(): string {
    if (!this.value) return '';
    if (this.showTime) {
      // Format for datetime-local: YYYY-MM-DDTHH:mm
      const year = this.value.getFullYear();
      const month = String(this.value.getMonth() + 1).padStart(2, '0');
      const day = String(this.value.getDate()).padStart(2, '0');
      const hours = String(this.value.getHours()).padStart(2, '0');
      const minutes = String(this.value.getMinutes()).padStart(2, '0');
      return `${year}-${month}-${day}T${hours}:${minutes}`;
    }
    return this.value.toISOString().split('T')[0];
  }

  getMinDateString(): string {
    if (!this.minDate) return '';
    if (this.showTime) {
      const year = this.minDate.getFullYear();
      const month = String(this.minDate.getMonth() + 1).padStart(2, '0');
      const day = String(this.minDate.getDate()).padStart(2, '0');
      const hours = String(this.minDate.getHours()).padStart(2, '0');
      const minutes = String(this.minDate.getMinutes()).padStart(2, '0');
      return `${year}-${month}-${day}T${hours}:${minutes}`;
    }
    return this.minDate.toISOString().split('T')[0];
  }

  getMaxDateString(): string {
    if (!this.maxDate) return '';
    if (this.showTime) {
      const year = this.maxDate.getFullYear();
      const month = String(this.maxDate.getMonth() + 1).padStart(2, '0');
      const day = String(this.maxDate.getDate()).padStart(2, '0');
      const hours = String(this.maxDate.getHours()).padStart(2, '0');
      const minutes = String(this.maxDate.getMinutes()).padStart(2, '0');
      return `${year}-${month}-${day}T${hours}:${minutes}`;
    }
    return this.maxDate.toISOString().split('T')[0];
  }

  onDateInput(event: Event) {
    const target = event.target as HTMLInputElement;
    const inputValue = target.value;

    if (!inputValue) {
      this.value = null;
      this.errorMessage = '';
      this.onChange.emit(null);
      this.onChangeFn(null);
      return;
    }

    const parsedDate = new Date(inputValue);
    if (!isNaN(parsedDate.getTime())) {
      this.value = parsedDate;
      this.errorMessage = '';
      this.onChange.emit(parsedDate);
      this.onChangeFn(parsedDate);
    } else {
      this.errorMessage = 'Invalid date format';
    }
  }

  clear() {
    this.value = null;
    this.errorMessage = '';
    this.onChange.emit(null);
    this.onChangeFn(null);
  }

  onBlur() {
    this.onTouched();
  }

  onKeydown(event: KeyboardEvent) {
    // Handle any keyboard events if needed
  }

  onInputClick() {
    // Focus the input to ensure calendar opens
    if (!this.disabled) {
      this.inputEl.nativeElement.focus();
      // Trigger the native date picker
      this.inputEl.nativeElement.showPicker?.();
    }
  }
}