import {
  Service,
  CharacteristicGetCallback,
  PlatformAccessory,
} from "homebridge";
import { Monitor, IStateChangeEventArgs } from "./monitor";
import { HomeLocationPlatform } from "./homeLocationPlatform";
import { IRoom } from "./config";

/**
 * Platform Accessory
 * An instance of this class is created for each accessory your platform registers
 * Each accessory may expose multiple services of different service types.
 */
export class LocationAccessory {
  private _services: Array<Service>;

  constructor(
    private readonly _platform: HomeLocationPlatform,
    private readonly _accessory: PlatformAccessory,
    private _monitor: Monitor,
    private _room: IRoom
  ) {
    this._services = [];
    // set accessory information
    this._accessory
      .getService(this._platform.Service.AccessoryInformation)!
      .setCharacteristic(
        this._platform.Characteristic.Manufacturer,
        "Brandon Watson"
      )
      .setCharacteristic(
        this._platform.Characteristic.Model,
        "Person Location Sensor"
      )
      .setCharacteristic(
        this._platform.Characteristic.SerialNumber,
        "123-456-789"
      );

    //Init motion services
    for (const label of this._monitor.labels) {
      const newService =
        this._accessory.getService(label) ||
        this._accessory.addService(
          this._platform.Service.MotionSensor,
          label,
          this._room + label
        );

      newService
        .getCharacteristic(this._platform.Characteristic.MotionDetected)
        .on("get", (callback: CharacteristicGetCallback) =>
          this.onMotionDetectedGet(label, callback)
        );

      this._services.push(newService);
    }

    //Register monitor state change events
    this._monitor.stateChangedEvent.push(this.onMonitorStateChange.bind(this));
  }

  private onMotionDetectedGet = (
    label: string,
    callback: CharacteristicGetCallback
  ) => {
    this._platform.log.debug("Triggered GET MotionDetected");

    // set this to a valid value for MotionDetected
    const currentValue =
      this._monitor.getState(label) === this._room.name ? 1 : 0;

    callback(null, currentValue);
  };

  private onMonitorStateChange = (
    sender: Monitor,
    args: IStateChangeEventArgs
  ) => {
    const service = this._services.find(
      (service) => service.displayName == args.label
    );
    if (service) {
      service.setCharacteristic(
        this._platform.Characteristic.MotionDetected,
        args.new === this._room.name
      );
    }
  };
}
