import { Injectable } from '@angular/core';
import { BaseButtonService } from './base-button.service';
import Swal from 'sweetalert2';

@Injectable({
  providedIn: 'root'
})
export class UpdateService extends BaseButtonService {

  private async_actions: { [key: string]: () => Promise<void> } = {};
  private actions: { [key: string]: () => void } = {};

  get asyncCount(): number {
    return Object.keys(this.async_actions).length;
  }

  get syncCount(): number {
    return Object.keys(this.actions).length;
  }

  get totalCount(): number {
    return this.asyncCount + this.syncCount;
  }

  get any(): boolean {
    return this.totalCount > 0;
  }

  //add - remove - executeA
  setAsync(key: string, action: () => Promise<void>): void {
    const keyWasPresent = this.async_actions.hasOwnProperty(key);
    this.async_actions[key] = action;
    if (!keyWasPresent)
      this.executeCountChangeListeners();
  }

  set(key: string, action: () => void): void {
    const keyWasPresent = this.actions.hasOwnProperty(key);
    this.actions[key] = action;
    if (!keyWasPresent)
      this.executeCountChangeListeners();
  }

  removeAll(): void {
    if (this.any) {
      this.async_actions = {};
      this.actions = {};
      this.executeCountChangeListeners();
    }
  }

  async executeAllAsync(): Promise<void> {
    const count = { err: 0, succ: 0, get all() { return this.err + this.succ } }
    await Promise.all(Object.values(this.async_actions).map(action => action().then(() => count.succ += 1).catch(() => count.err += 1)))
      .then(() => {
        if (count.err > 0)
          Swal.fire({
            icon: "info",
            title: "Verarbeitungsfehler",
            text: `Von ${count.all} Aktualisierungen wurden ${count.succ} erfolgreich durchgeführt, ${count.err} jedoch nicht. Der Fehler könnte durch den Versuch entstanden sein, persönliche Daten zu aktualisieren. Bitte überprüfen Sie dies.`,
          })
      });
    Object.values(this.actions).forEach(action => action());
    this.removeAll();
  }

  //change listeners
  //count
  private countChangeListeners: Array<() => void> = new Array();
  private executeCountChangeListeners() {
    this.countChangeListeners.forEach(e => e());
  }

  addChangeListener(eventType: UpdateEvent, action: () => void) {
    switch (eventType) {
      case UpdateEvent.CountChange:
        this.countChangeListeners.push(action)
        break;
    }
  }

  removeAllChangeListeners() {
    this.countChangeListeners = []
  }

  //cell edit
  private _isEditable: boolean = (typeof window !== 'undefined') ? (localStorage.getItem('editable') === "T") : true;
  public get isEditable(): boolean {
    return this._isEditable;
  }

  public set isEditable(value: boolean) {
    if (typeof window !== 'undefined')
      localStorage.setItem('editable', value ? "T" : "F")
    this._isEditable = value;
  }

  toggleEditability() {
    this.isEditable = !this.isEditable;
  }
}

export enum UpdateEvent {
  CountChange
}