import {inject, Injectable} from '@angular/core'
import {TaskService} from './task.service'
import {ILabel} from '../../models/ILabel'
import {Color} from '../../models/Color'
import {StorageService} from './storage.service'

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

  readonly #storageKey = 'labelStorage'
  #taskService = inject(TaskService)
  #storageService = inject(StorageService)

  #labels: ILabel[] = []

  constructor() {
    this.#loadLabels().then(() => console.log('Labels successfully loaded'))
  }

  /**
   * Retrieve a list of all the available labels.
   *
   * @return A list of each available label.
   */
  get labels(): ILabel[] {
    return window.structuredClone(this.#labels)
  }

  /**
   * Retrieve a specific label by its id.
   *
   * @param id The id of the label to retrieve.
   * @return The label with the given id, undefined if there is no such label.
   */
  getLabelById(id: string): ILabel | undefined {
    return window.structuredClone(this.labels.find(l => l.id === id))
  }

  /**
   * Delete a label by its id.
   *
   * @param id The id of the label that is to be deleted.
   */
  async deleteLabel(id: string): Promise<void> {
    this.#labels = this.#labels.filter(l => l.id !== id)
    this.#taskService.deleteLabelFromTasks(id)
    await this.#persistLabels()
  }

  /**
   * Create a new label with the given name and color.
   *
   * @param name The name of the new label.
   * @param color The color of the new label.
   */
  async createLabel(name: string, color: Color): Promise<void> {
    this.#labels.push({
      name,
      color,
      id: window.crypto.randomUUID(),
    })
    await this.#persistLabels()
  }

  /**
   * Persist all the labels in this service.
   */
  async #persistLabels(): Promise<void> {
    await this.#storageService.persistObjectData(this.#storageKey, this.#labels)
  }

  /**
   * Load the persisted labels or set the label list to an empty array.
   *
   * @private
   */
  async #loadLabels(): Promise<void> {
    this.#labels = await this.#storageService.loadJSONData<ILabel[]>(this.#storageKey) ?? []
  }
}
