import {Component, Injectable, Input, OnInit} from "@angular/core";
import {Observable, ReplaySubject} from "rxjs";
import {HttpClient} from "@angular/common/http";
import {PersonService} from "../person/person.service";
import * as _ from 'underscore';
import * as S from 'underscore.string';

@Component({
  selector: 'label-id',
  templateUrl: 'labeled.component.html'
})
export class LabeledComponent implements OnInit {

  @Input("default")
  public defaultLabel: string = '???'

  @Input("id")
  public id: string = null

  @Input("labelOnly")
  public labelOnly: boolean = false;

  public mode = 'view'

  public labelInput: string

  public label: Observable<String> = null

  constructor(private labeledService: LabeledService) {

  }

  edit() {
    this.label.subscribe(labelValue => {
      this.labelInput = labelValue ? labelValue.toString() : this.defaultLabel
      this.mode = 'edit'
    })
  }

  save() {
    this.labeledService.putLabel(this.id, !_.isEmpty(this.labelInput) ? this.labelInput : null).subscribe(res => {
      this.ngOnInit();
      this.mode = 'view'
    })
  }

  cancel() {
    this.mode = 'view'
  }

  keyPress(e: KeyboardEvent) {
    if (S(e.code).contains('Enter')) {
      this.save()
    } else if (S(e.code).contains('Esc')) {
      this.cancel()
    }
  }

  ngOnInit(): void {
    let repl = new ReplaySubject<string>()
    this.labeledService.getLabel(this.id, repl)
    this.label = repl
  }

}

@Injectable({providedIn: 'root'})
export class LabeledService {

  private cache = new Map<string, string>()

  constructor(private httpClient: HttpClient, private personService: PersonService) {
  }

  putLabel(id: string, label: string): Observable<LabelResp> {
    let ret = new ReplaySubject<LabelResp>();
    this.cache.delete(id)
    this.personService.getCurrentPerson().subscribe(person => this.httpClient.post(`/api/old/person/${person.auth.id}/opts/label/${id}`, {label}).subscribe((res: LabelResp) => ret.next(res)))
    return ret;
  }

  getLabel(id: string, repl: ReplaySubject<string>) {
    if (this.cache.has(id)) {
      setTimeout(() => {
        repl.next(this.cache.get(id))
      }, 10)
    } else {
      this.personService.getCurrentPerson().subscribe(person => {
        this.httpClient.get(`/api/old/person/${person.auth.id}/opts/label/${id}`).subscribe((res: LabelResp) => {
          repl.next(res?.label)
          this.cache.set(id, res?.label)
        })
      })
    }
  }
}

class LabelResp {
  labelId: string
  label: string
}
