import {Component} from '@angular/core';
import {RecipeService} from "../../services/recipe.service";
import {ActivatedRoute, Router} from "@angular/router";
import {SubscribingComponent} from "../../../shared/components/subscribing.component";
import {Recipe} from "../../../shared/model/recipe.model";
import {Observable, Subject} from "rxjs";
import {UNIT_GALLON, UNIT_LITER, UNIT_MILLILITER} from "../../../shared/units";

@Component({
  selector: 'cre-explore',
  templateUrl: './explore.component.html',
  styleUrls: ['./explore.component.sass']
})
export class ExploreComponent extends SubscribingComponent {
  readonly unitConstants = {UNIT_MILLILITER, UNIT_LITER, UNIT_GALLON}

  recipe: Recipe | null
  error: string
  deductErrorBody = {}
  success: string
  units$ = new Subject<string>()

  hasModifications = false
  note: string | null
  quantitiesChanges = new Map<number, Map<number, number>>()
  mixesLocationChanges = new Map<number, string>()
  printingError = 2

  // Errors
  readonly ERROR_UNKNOWN = 'unknown'
  readonly ERROR_DEDUCT = 'deduct'
  // Success
  readonly SUCCESS_SAVE = 'save'
  readonly SUCCESS_DEDUCT = 'deduct'

  constructor(
    private recipeService: RecipeService,
    router: Router,
    activatedRoute: ActivatedRoute
  ) {
    super(activatedRoute, router)
  }

  ngOnInit(): void {
    super.ngOnInit()

    const id = parseInt(this.activatedRoute.snapshot.paramMap.get('id'))
    this.subscribe(
      this.recipeService.getById(id),
      {
        next: r => {
          this.recipe = r
          this.note = r.note
        },
        error: err => this.handleNotFoundError(err, '/colors/list')
      },
      1
    )
  }

  changeUnits(unit: string) {
    this.units$.next(unit)
  }

  changeNote(event: any) {
    this.hasModifications = true
    this.note = event.target.value
  }

  changeQuantity(event: { id: number, materialId: number, quantity: number }) {
    if (!this.quantitiesChanges.has(event.id)) this.quantitiesChanges.set(event.id, new Map<number, number>())
    this.quantitiesChanges.get(event.id).set(event.materialId, event.quantity)
  }

  changeMixLocation(event: { id: number, location: string }) {
    this.hasModifications = true
    this.mixesLocationChanges.set(event.id, event.location)
  }

  saveModifications() {
    this.subscribe(
      this.recipeService.saveExplorerModifications(this.recipe.id, this.note, this.mixesLocationChanges),
      {
        next: () => {
          this.hasModifications = false
          this.error = null
          this.success = this.SUCCESS_SAVE
        },
        error: err => {
          this.success = null
          this.error = this.ERROR_UNKNOWN
          console.error(err)
        }
      },
      1
    )
  }

  deductQuantities() {
    this.performDeductQuantities(this.recipeService.deductQuantities(this.recipe, this.quantitiesChanges))
  }

  deductMixQuantities(mixId: number) {
    this.performDeductQuantities(this.recipeService.deductMixQuantities(this.recipe, mixId, this.quantitiesChanges.get(mixId)))
  }

  performDeductQuantities(observable: Observable<void>) {
    this.subscribe(
      observable,
      {
        next: () => {
          this.error = null
          this.success = this.SUCCESS_DEDUCT
        },
        error: err => {
          this.success = null
          if (err.status === 409) { // There is not enough of one or more materials in the inventory
            this.error = this.ERROR_DEDUCT
            this.deductErrorBody = err.error
          } else {
            this.error = this.ERROR_UNKNOWN
            console.error(err)
          }
        }
      },
      1
    )
  }
}
