import { Component, OnInit, Input, OnDestroy } from '@angular/core';
import { Observable, Subscription } from 'rxjs';
import { Pump, PumpWithStatus } from 'src/app/models/pump';
import { Sensor, SensorWithStatus } from 'src/app/models/sensor';
import { Log } from 'src/app/models/log';
import { StatusService } from './status.service';
import { ActivatedRoute } from '@angular/router';
import { Router } from '@angular/router';
import { PumpStatus } from 'src/app/models/pumpStatus';
import { SensorStatus } from 'src/app/models/SensorStatus';
import { Result } from 'postcss';
import { interval } from 'rxjs';
import { take } from 'rxjs/operators';

@Component({
  selector: 'app-status',
  templateUrl: './status.component.html',
  styleUrls: ['./status.component.css'],
})
export class StatusComponent implements OnInit, OnDestroy {
  @Input() log: Log = {
    id: 0,
    description: '',
    isDismissed: false,
    timestamp: '',
    wharfID: 0,
    logTypeID: 1
  };

  @Input() pumpWithStatus: PumpWithStatus = {
    id: 0,
    gridPos: '',
    description: '',
    pumpModelID: 0,
    wharfID: 0,
    isOn: false,
    isOnAtWharf: false,
    pumpStatusId: 0,
    timestamp: ''
  }

  @Input() sensorWithStatus: SensorWithStatus = {
    id: 0,
    gridPos: '',
    description: '',
    batteryPercentage: 0,
    wharfID: 0,
    isOn: false,
    isOnAtWharf: false,
    sensorStatusId: 0,
    timestamp: ''
  }

  @Input() pumpStatus: PumpStatus = {
    id: 0,
    pumpID: 0,
    isOn: 0,
    isOnAtWharf: 0,
    timestamp: ''
  };

  @Input() sensorStatus: SensorStatus = {
    id: 0,
    sensorID: 0,
    isOn: false,
    isOnAtWharf: false,
    timestamp: ''
  }

  wharfId = 0;
  errorMessage: string = '';

  pumpWithStatus$: Observable<PumpWithStatus[]> = new Observable<PumpWithStatus[]>();
  pumpWithStatusLoop$: Subscription = new Subscription();
  sensorWithStatus$: Observable<SensorWithStatus[]> = new Observable<SensorWithStatus[]>();
  sensorWithStatusLoop$: Subscription = new Subscription();
  postLog$: Subscription = new Subscription();
  postPumpStatus$: Subscription = new Subscription();
  putPumpStatus$: Subscription = new Subscription();
  postSensorStatus$: Subscription = new Subscription();
  putSensorStatus$: Subscription = new Subscription();

  constructor(
    private statusService: StatusService,
    private route: ActivatedRoute,
    private router: Router
  ) {}

  ngOnInit(): void {
    this.wharfId = parseInt(JSON.parse(this.route.snapshot.paramMap.get('wharIid') || '{}'));
    this.pumpWithStatus$ = this.statusService.getPumpsWithStatus();
    this.sensorWithStatus$ = this.statusService.getSensorsWithStatus();
  }

  ngOnDestroy(): void {
    this.pumpWithStatusLoop$.unsubscribe();
    this.postLog$.unsubscribe();
    this.postPumpStatus$.unsubscribe();
    this.putPumpStatus$.unsubscribe();
    this.postSensorStatus$.unsubscribe();
    this.sensorWithStatusLoop$.unsubscribe();
    this.putSensorStatus$.unsubscribe();
  }

  // sleep functie die gebruikt wordt bij de status van de pomp en de sensor
  sleep = (ms: number) => new Promise(r => setTimeout(r, ms));

  // status pomp wordt aangepast
  toggleOnAndOffSwitchPump(pumpId: number, event:Event, gridpos: string){
    {(event.target as HTMLInputElement).checked ? this.addLog(pumpId, 'aangezet', 'pomp') : this.addLog(pumpId, 'uitgeschakeld', 'pomp')};
    this.statusChangePump(pumpId, gridpos, (event.target as HTMLInputElement).checked);
  }

  async statusChangePump(id: number, gridpos: string, isOnInFront: boolean){
    var isOnInDb = false;
    var isOnAtWharf = false;
    for (let i = 0; i < 12; i++) {
      this.pumpWithStatusLoop$ = this.statusService.getPumpsWithStatus().subscribe(resulst => {
        resulst.forEach(element => {
          if(id == element.id){
            var strId = id.toString().concat(gridpos.toString());
            isOnInDb = element.isOn;
            isOnAtWharf = element.isOnAtWharf;

            var status = document.getElementById(id.toString().concat(gridpos.toString()));
            if (status){
              status.innerHTML = 'Pending ...';
            }

            // als de status in de db nog niet aangepast is posten we een nieuwe status, vanaf de 2de check posten we op de laatste status
            if (isOnInDb !== isOnInFront && i == 0) {
              if (isOnInFront == true) {
                this.pumpStatus.isOn = 1;
              } else {
                this.pumpStatus.isOn = 0;
              }
              this.pumpStatus.pumpID = id;
              let new_Date: Date = new Date();
              this.pumpStatus.timestamp = new_Date.toLocaleString("sv-SE", {dateStyle: "short",timeStyle: "medium"}).replace(/ /g, 'T').concat(".000Z");
              this.postPumpStatus$ = this.statusService.postPumpStatus(this.pumpStatus).subscribe({
                error: (e) => this.errorMessage += e.message
              });
            } else if (isOnInDb !== isOnInFront) {
              this.putPumpStatus$ = this.statusService.putPumpStatus(this.pumpStatus, element.pumpStatusId).subscribe({
                error: (e) => this.errorMessage += e.message
              });
            }
          }
        });
      });
      await this.sleep(5000);
    }
    if (isOnInDb != isOnInFront){
      this.errorMessage += 'Kon status pomp ' + id + ' niet aanpassen in de database! Herlaad de pagina en probeer opnieuw.';
    }

    if (isOnInDb != isOnAtWharf){
      var status = document.getElementById(id.toString().concat(gridpos.toString()));
      if (status){
        status.innerHTML = 'Error';
      }
    } else {
      var status = document.getElementById(id.toString().concat(gridpos.toString()));
      if (status){
        status.innerHTML = 'Correct';
      }
    }
  }

  // status sensor wordt aangepast
  toggleOnAndOffSwitchSensor(sensorId: number, event:Event, gridpos: string){
    {(event.target as HTMLInputElement).checked ? this.addLog(sensorId, 'aangezet', 'sensor') : this.addLog(sensorId, 'uitgeschakeld', 'sensor')};
    // {(event.target as HTMLInputElement).checked ? this.addSensorStatus(sensorId, true) : this.addSensorStatus(sensorId, false)};
    this.statusChangeSensor(sensorId, gridpos, (event.target as HTMLInputElement).checked);
  }

  async statusChangeSensor(id: number, gridpos: string, isOnInFront: boolean){
    var isOnInDb = false;
    var isOnAtWharf = false;
    for (let i = 0; i < 12; i++) {
      this.sensorWithStatusLoop$ = this.statusService.getSensorsWithStatus().subscribe(resulst => {
        resulst.forEach(element => {
          if(id == element.id){
            var strId = id.toString().concat(gridpos.toString());
            isOnInDb = element.isOn;
            isOnAtWharf = element.isOnAtWharf;

            var status = document.getElementById(id.toString().concat(gridpos.toString()));
            if (status){
              status.innerHTML = 'Pending ...';
            }

            // als de status in de db nog niet aangepast is posten we een nieuwe status, vanaf de 2de check posten we op de laatste status
            if (isOnInDb !== isOnInFront && i == 0) {
              this.sensorStatus.isOn = isOnInFront
              this.sensorStatus.sensorID = id;
              let new_Date: Date = new Date();
              this.sensorStatus.timestamp = new_Date.toLocaleString("sv-SE", {dateStyle: "short",timeStyle: "medium"}).replace(/ /g, 'T').concat(".000Z");
              this.postSensorStatus$ = this.statusService.postSensorStatus(this.sensorStatus).subscribe({
                error: (e) => this.errorMessage += e.message
              });
            } else if (isOnInDb !== isOnInFront) {
              this.putSensorStatus$ = this.statusService.putSensorStatus(this.sensorStatus, element.sensorStatusId).subscribe({
                error: (e) => this.errorMessage += e.message
              });
            }
          }
        });
      });
      await this.sleep(5000);
    }
    if (isOnInDb != isOnInFront){
      this.errorMessage += 'Kon status sensor ' + id + ' niet aanpassen in de database! Herlaad de pagina en probeer opnieuw.';
    }

    if (isOnInDb != isOnAtWharf){
      var status = document.getElementById(id.toString().concat(gridpos.toString()));
      if (status){
        status.innerHTML = 'Error';
      }
    } else {
      var status = document.getElementById(id.toString().concat(gridpos.toString()));
      if (status){
        status.innerHTML = 'Correct';
      }
    }
  }

  addSensorStatus(id: number, status: boolean) {
    this.sensorStatus.isOn = status;
    this.sensorStatus.sensorID = id;
    let new_Date: Date = new Date();
    this.sensorStatus.timestamp = new_Date.toLocaleString("sv-SE", {dateStyle: "short",timeStyle: "medium"}).replace(/ /g, 'T').concat(".000Z");

    this.postSensorStatus$ = this.statusService.postSensorStatus(this.sensorStatus).subscribe({
      error: (e) => this.errorMessage = e.message
    });
  }


  // Bij het handmatig aanpassen van een pomp of sensor status wordt dit in de logs gezet
  addLog(id: number, boodschap: string, type: string) {
    this.log.wharfID = parseInt(JSON.parse(this.route.snapshot.paramMap.get('wharIid') || '{}'));
    this.log.description = type + ' ' + id + ' ' + boodschap;
    this.log.wharfID = this.wharfId;
    let new_Date: Date = new Date();

    this.log.timestamp = new_Date.toLocaleString("sv-SE", {dateStyle: "short",timeStyle: "medium"}).replace(/ /g, 'T').concat(".000Z");


    this.postLog$ = this.statusService.postLog(this.log).subscribe({
      error: (e) => (this.errorMessage = e.message),
    });
  }

}
