import {Component, EventEmitter, Input, Output, ViewChild} from '@angular/core';
import {Mix, MixMaterial, Recipe} from "../../../shared/model/recipe.model";
import {SubscribingComponent} from "../../../shared/components/subscribing.component";
import {MixService} from "../../services/mix.service";
import {Observable} from "rxjs";
import {RecipeService} from "../../services/recipe.service";
import {Material} from "../../../shared/model/material.model";
import {MaterialService} from "../../../material/service/material.service";
import {MaterialType} from "../../../shared/model/materialtype.model";
import {MaterialTypeService} from "../../../material-type/service/material-type.service";
import {FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms";
import {UNIT_MILLILITER} from "../../../shared/units";
import {MatTable} from "@angular/material/table";
import {ActivatedRoute, Router} from "@angular/router";
import {ConfirmBoxComponent} from "../../../shared/components/confirm-box/confirm-box.component";
import {AccountService} from "../../../accounts/services/account.service";
import {EmployeePermission} from "../../../shared/model/employee";

@Component({
  selector: 'cre-mix-editor',
  templateUrl: './mix-editor.component.html',
  styleUrls: ['./mix-editor.component.sass']
})
export class MixEditorComponent extends SubscribingComponent {
  @ViewChild('mixTable') mixTable: MatTable<MixMaterial>
  @ViewChild('deleteConfirmBox') deleteConfirmBox: ConfirmBoxComponent

  @Input() mixId: number | null
  @Input() recipeId: number | null
  @Input() materials: Material[]

  @Output() save = new EventEmitter<any>();

  mix: Mix | null
  recipe: Recipe | null
  materialTypes$: Observable<MaterialType[]>

  form: FormGroup
  nameControl: FormControl
  materialTypeControl: FormControl

  mixMaterials = []
  editionMode = false
  units = UNIT_MILLILITER
  hoveredMixMaterial: MixMaterial | null
  columns = ['position', 'material', 'quantity', 'units', 'buttonRemove']

  constructor(
    private mixService: MixService,
    private recipeService: RecipeService,
    private materialService: MaterialService,
    private materialTypeService: MaterialTypeService,
    private accountService: AccountService,
    private formBuilder: FormBuilder,
    router: Router,
    activatedRoute: ActivatedRoute
  ) {
    super(activatedRoute, router)
  }

  ngOnInit() {
    super.ngOnInit();

    this.mixId = this.urlUtils.parseIntUrlParam('id')
    if (this.mixId) {
      this.editionMode = true
    }

    this.subscribe(
      this.recipeService.getById(this.recipeId),
      {
        next: r => {
          this.recipe = r
          if (this.editionMode) {
            this.subscribe(
              this.mixService.getById(this.mixId),
              {
                next: m => {
                  this.mix = m
                  this.mixMaterials = this.mixService.extractMixMaterials(this.mix)
                  this.generateForm()
                }, error: err => this.handleNotFoundError(err, '/color/list')
              }
            )
          } else {
            this.mixMaterials.push({})
            this.generateForm()
          }
        },
        error: err => this.handleNotFoundError(err, '/color/list')
      }
    )
    this.materialTypes$ = this.materialTypeService.all
  }

  addRow() {
    this.mixMaterials.push({materialId: null, quantity: null, percents: false})
    this.mixTable.renderRows()
  }

  removeRow(position: number) {
    this.mixMaterials.splice(position, 1)
    this.mixTable.renderRows()
  }

  submit() {
    this.save.emit({
      name: this.nameControl.value,
      recipeId: this.recipeId,
      materialTypeId: this.materialTypeControl.value,
      mixMaterials: this.mixMaterials,
      units: this.units
    })
  }

  delete() {
    this.subscribeAndNavigate(this.mixService.delete(this.mixId), `/color/edit/${this.recipeId}`)
  }

  materialUsePercentages(mixMaterial: any) {
    if (!mixMaterial.materialId) return null
    const material = this.getMaterialFromId(mixMaterial.materialId);
    mixMaterial.percents = material && material.materialType.usePercentages
    return mixMaterial.percents
  }

  getMaterialFromId(id: number): Material {
    return id ? this.materials.filter(m => m.id === id)[0] : null
  }

  get canDeleteMix() {
    return this.accountService.hasPermission(EmployeePermission.REMOVE_RECIPE)
  }

  private generateForm() {
    this.nameControl = new FormControl(this.mix ? this.mix.mixType.name : null, Validators.required)
    this.materialTypeControl = new FormControl(this.mix ? this.mix.mixType.material.materialType.id : null, Validators.required)
    this.form = this.formBuilder.group({
      name: this.nameControl,
      materialType: this.materialTypeControl
    })
  }
}
