import {Injectable} from '@angular/core';
import {ApiService} from "../../shared/service/api.service";
import {convertMixMaterialQuantity, UNIT_MILLILITER} from "../../shared/units";
import {Observable} from "rxjs";
import {Mix} from "../../shared/model/recipe.model";

@Injectable({
  providedIn: 'root'
})
export class MixService {
  constructor(
    private api: ApiService
  ) {
  }

  get all(): Observable<Mix[]> {
    return this.api.get<Mix[]>('/recipe/mix')
  }

  getById(id: number): Observable<Mix> {
    return this.api.get<Mix>(`/recipe/mix/${id}`)
  }

  saveWithUnits(name: string, recipeId: number, materialTypeId: number, mixMaterials: { materialId: number, quantity: number, percents: boolean }[], units: string): Observable<void> {
    return this.save(name, recipeId, materialTypeId, this.convertMixMaterialsToMl(mixMaterials, units))
  }

  save(name: string, recipeId: number, materialTypeId: number, mixMaterials: { materialId: number, quantity: number }[]): Observable<void> {
    const body = {
      name,
      recipeId,
      materialTypeId,
      mixMaterials: {}
    }
    this.appendMixMaterialsToBody(mixMaterials, body)
    return this.api.post('/recipe/mix', body)
  }

  updateWithUnits(id: number, name: string, materialTypeId: number, mixMaterials: { materialId: number, quantity: number, percents: boolean }[], units: string): Observable<void> {
    return this.update(id, name, materialTypeId, this.convertMixMaterialsToMl(mixMaterials, units))
  }

  update(id: number, name: string, materialTypeId: number, mixMaterials: { materialId: number, quantity: number }[]): Observable<void> {
    const body = {
      id,
      name,
      materialTypeId,
      mixMaterials: {}
    }
    this.appendMixMaterialsToBody(mixMaterials, body)
    return this.api.put('/recipe/mix', body)
  }

  delete(id: number): Observable<void> {
    return this.api.delete(`/recipe/mix/${id}`)
  }

  extractMixMaterials(mix: Mix): { materialId: number, quantity: number, percents: boolean }[] {
    return mix.mixMaterials.map(m => {
      return {materialId: m.material.id, quantity: m.quantity, percents: m.material.materialType.usePercentages}
    })
  }

  private convertMixMaterialsToMl(mixMaterials: { materialId: number, quantity: number, percents: boolean }[], units: string): { materialId: number, quantity: number }[] {
    return mixMaterials.map(m => {
      return {
        materialId: m.materialId,
        quantity: convertMixMaterialQuantity(m, units, UNIT_MILLILITER)
      }
    })
  }

  private appendMixMaterialsToBody(mixMaterials: { materialId: number, quantity: number }[], body: any) {
    mixMaterials
      .filter(m => m.materialId != null && m.quantity != null)
      .forEach(m => body.mixMaterials[m.materialId] = m.quantity)
  }
}

