import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators} from '@angular/forms';
import {ManagementService} from '../../../shared/api/endpoints/services/management.service';
import {InsertUnit} from '../../../shared/api/endpoints/models/insert-unit';
import {InsertSensor} from '../../../shared/api/endpoints/models/insert-sensor';
import {map} from 'rxjs/operators';
import {HttpResponse} from '@angular/common/http';
import {ToastService} from '../../../shared/services/toast.service';
import {SensorType} from '../../../shared/api/endpoints/models/sensor-type';
import {Phenomenon} from '../../../shared/api/endpoints/models/phenomenon';

@Component({
  selector: 'app-sensor-insert-popup',
  templateUrl: './sensor-insert-popup.component.html',
  styleUrls: ['./sensor-insert-popup.component.scss']
})
export class SensorInsertPopupComponent implements OnInit {

  insertForm: UntypedFormGroup;
  items: UntypedFormArray;
  sensors = 0;

  @Input() phenomenons: Phenomenon[];
  @Input() isVisible;
  @Input() unit;
  @Input() sensorTypes: SensorType[];
  @Output() isVisibleChange: EventEmitter<boolean> = new EventEmitter<boolean>();
  @Output() emitNewSensor: EventEmitter<{unit: InsertUnit, sensors: InsertSensor[]}> =
    new EventEmitter<{unit: InsertUnit, sensors: InsertSensor[]}>()

  constructor(
    private formBuilder: UntypedFormBuilder,
    private managementService: ManagementService,
    private toastService: ToastService
  ) {
    this.initForm();
  }

  ngOnInit(): void {
  }

  close() {
    this.isVisibleChange.emit(false);
  }

  initForm() {
    this.insertForm = this.formBuilder.group({
      sensors: this.formBuilder.array([this.createSensor()])
    });
  }

  /**
   * Prepare form object for sensor
   */
  createSensor(): UntypedFormGroup {
    return this.formBuilder.group({
      sensorId: ['', Validators.required],
      sensorName: ['', Validators.required],
      sensorType: ['null', Validators.required],
      phenomenons: ['null', Validators.required]
    });
  }

  /**
   * Add sensor to form
   */
  addSensor(): void {
    this.items = this.insertForm.get('sensors') as UntypedFormArray;
    this.items.push(this.createSensor());
    this.sensors++;
  }

  /**
   * Remove last sensor from form
   */
  removeSensor() {
    this.items = this.insertForm.get('sensors') as UntypedFormArray;
    this.items.removeAt(this.items.length - 1);
    this.sensors--;
  }

  /**
   * Clearing form
   */
  clearFormArray() {
    const frmArray = this.insertForm?.get('sensors') as UntypedFormArray;
    if (frmArray) {
      frmArray.clear();
    }
    this.addSensor();
    this.insertForm.reset();
  }

  /**
   * Send insert sensors request to backend. Iterate over all sensors in form.
   */
  processSensorInsertion() {
    if (this.insertForm.valid) {
      const unit: InsertUnit = {
        unit_id: this.unit.unitId
      }
      const sensors: InsertSensor[] = [];
      const frmArray = this.insertForm?.get('sensors') as UntypedFormArray;

      frmArray.controls.forEach(control => {
        if (control.get('sensorId').value !== '') {
          const sensor: InsertSensor = {
            sensor_id: control.get('sensorId').value,
            sensor_name: control.get('sensorName').value,
            sensor_type: control.get('sensorType').value,
            phenomenon: {
              phenomenon_id: control.get('phenomenons').value
            },
          }
          sensors.push(sensor);
        }
      });

      this.managementService.insertSensor$Response({body: {unit, sensors}}).pipe(
        map((response: HttpResponse<any>) => {
          if (response.status === 200) {
            this.toastService.showSuccessMessage('Sensors inserted to unit!');
            this.emitNewSensor.emit({unit, sensors});
            this.close();
          } else {
          }
        })
      ).toPromise().then().catch(err => this.toastService.showError(err.error.message));
    }
  }
}
