import { Component, OnInit, OnDestroy } from '@angular/core';
import { CurrentDeviceService, TapInfo } from '@iotize/ionic';
import { ConnectionStateChangeEvent, ConnectionState } from '@iotize/device-client.js/protocol/api';
import { Subscription, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { ModalController } from '@ionic/angular';
import { TapMonitoringSettingsComponent, MonitoringSettingsService, SubVariableInteraction } from '@iotize/ionic';
import { VariableInteraction } from '@iotize/device-client.js/device/target-variable/variable-interaction.interface';
import { <%= classify(appName) %> } from '<%= tapApiImportPath %>';
import { VariableConfig } from '@iotize/device-client.js/device/target-variable/variable';
import { Router, NavigationStart } from '@angular/router';
import { Tap } from '@iotize/device-client.js/device';

@Component({
  selector: '<%= dasherize(name) %>',
  templateUrl: './<%= dasherize(name) %>.component.html',
  styleUrls: ['./<%= dasherize(name) %>.component.scss'],
})
export class <%= classify(name) %>Component implements OnInit, OnDestroy {
  private connectionStateChangeSub: Subscription;
  private monitoringSettingsSub: Subscription;
  private routeSub: Subscription;
  private _subVariableCache: Record<string, SubVariableInteraction<any>> = {};

  waitForSubmit: boolean = false;
  isMonitorRunning: boolean = false;
  data ?: <%= classify(appName) %>.DataManager;

  constructor(public tapService: CurrentDeviceService
    , private modalController: ModalController
    , private monitoringSettingsService: MonitoringSettingsService
    , private router: Router) {
  }

  <%= renderEngine.renderTS('declaration', content) %>

  async ngOnInit() {
    this.data = <%= classify(appName) %>.DataManager.create(this.tap);
    this.initComponents();
    this.tapService
      .tapChanged
      .subscribe((newTap: Tap) => {
        // debug('Tap changed!');
        if (this.data){
          this.data.stopAll();
        }
        this.data = <%= classify(appName) %>.DataManager.create(newTap);
        this.initComponents();
      });
    
    this.waitForSubmit = !this.tapService.tap.isConnected();

    this.connectionStateChangeSub = this.tapService
      .connectionState
      .subscribe((event: ConnectionStateChangeEvent) => {
        switch (event.newState) {
          case ConnectionState.CONNECTED:
            this.waitForSubmit = false;
            break;
          default:
            this.waitForSubmit = true;
        }
      });
      
    this.monitoringSettingsSub = this.monitoringSettingsService
      .settings$
      .subscribe((newSettings) => {
        this.data.setMonitoringPeriod(newSettings.period);
      });

    this.routeSub = this.router.events.subscribe((event) => {
      if (event instanceof NavigationStart) {
        this.stopMonitor();
      }
    });

    this.startMonitor();
  }

  public initComponents(){
    <%= renderEngine.renderTS('init', content) %>
  }

  ngOnDestroy() {
    this.connectionStateChangeSub.unsubscribe();
    this.monitoringSettingsSub.unsubscribe();
    this.routeSub.unsubscribe();
  }
  
  get variables() {
    return this.data.variables;
  }

  subVariable(variable: VariableConfig<any[]>, index: number){
    let key = `${variable.identifier()}.${index}`;
    if (!(key in this._subVariableCache)){
      this._subVariableCache[key] = new SubVariableInteraction(variable, index);
    }
    return  this._subVariableCache[key];
  }

  get tap() {
    return this.tapService.tap;
  }

  get isMonitoringRunning(){
    return this.data && this.data.isMonitoringRunning;
  }

  stopMonitor() {
    this.data.stopAll();
  }

  async startMonitor() {
    await this.tap.service.target.connect().catch((err) => console.warn(err));
    this.data.startAll(
      this.monitoringSettingsService.settings.period
    );
  }

  async openSettings() {
    const modal = await this.modalController.create({
      component: TapMonitoringSettingsComponent,
    });

    return await modal.present();
  }

  selectDevice(){
    this.router.navigateByUrl('/connect');
  }
}
