import { ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core';
import { FormControl, Validators } from '@angular/forms';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

@Component({
  selector: 'ui-notes',
  templateUrl: 'ui-notes.component.html',
  styleUrls: ['ui-notes.component.scss'],
})
export class UiNotesComponent implements OnChanges, OnInit, OnDestroy {
  @Input()
  maxNotes: number;

  @Input()
  notes: { note: string; date: Date }[] = [];

  notesToDisplay: { note: string; date: Date }[] = [];

  @Output()
  add = new EventEmitter<string>();

  @Input()
  value: string;

  @Output()
  valueChange = new EventEmitter<string>();

  control = new FormControl('', [Validators.required]);

  private onDestroy$ = new Subject();

  constructor(private cdr: ChangeDetectorRef) {}

  ngOnInit() {
    this.control.valueChanges.pipe(takeUntil(this.onDestroy$)).subscribe(this.valueChange);
  }

  ngOnDestroy() {
    this.onDestroy$.next();
    this.onDestroy$.complete();
  }

  ngOnChanges({ notes, maxNotes, value }: SimpleChanges) {
    if (notes || maxNotes || value) {
      if ((value || this.value) && this.value !== this.control.value) {
        this.control.patchValue(this.value);
        this.control.markAsDirty();
      }
      this.updateNotesToDisplay();
    }
  }

  updateNotesToDisplay() {
    if (Array.isArray(this.notes)) {
      let notes = [...this.notes?.sort((a, b) => b.date.getTime() - a.date.getTime())];
      if (this.maxNotes > 0) {
        notes = notes.slice(0, this.maxNotes);
      }
      this.notesToDisplay = notes;
    } else {
      this.notesToDisplay = [];
    }
    this.cdr.markForCheck();
  }

  addNote() {
    if (this.control.dirty && this.control.valid) {
      const value = this.control.value;
      this.add.emit(value);
      this.control.reset();

      this.notes = [{ note: value, date: new Date() }, ...this.notes];
      this.updateNotesToDisplay();
    }
  }
}
