"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var DoorLock_exports = {};
__export(DoorLock_exports, {
  DoorLockCCBehaviors: () => DoorLockCCBehaviors
});
module.exports = __toCommonJS(DoorLock_exports);
var import_cc = require("@zwave-js/cc");
var import_DoorLockCC = require("@zwave-js/cc/DoorLockCC");
var import_core = require("@zwave-js/core");
var import_shared = require("@zwave-js/shared");
const defaultCapabilities = {
  supportedOperationTypes: [import_cc.DoorLockOperationType.Constant],
  supportedDoorLockModes: [import_cc.DoorLockMode.Unsecured, import_cc.DoorLockMode.Secured],
  supportedOutsideHandles: [true, true, true, true],
  supportedInsideHandles: [true, true, true, true],
  doorSupported: true,
  boltSupported: true,
  latchSupported: true,
  blockToBlockSupported: false,
  twistAssistSupported: false,
  holdAndReleaseSupported: false,
  autoRelockSupported: false,
  travelTime: 0
};
const STATE_KEY_PREFIX = "DoorLock_";
const StateKeys = {
  currentMode: `${STATE_KEY_PREFIX}currentMode`,
  transition: `${STATE_KEY_PREFIX}transition`,
  operationType: `${STATE_KEY_PREFIX}operationType`,
  outsideHandlesCanOpenDoorConfiguration: `${STATE_KEY_PREFIX}outsideHandlesCanOpenDoorConfiguration`,
  insideHandlesCanOpenDoorConfiguration: `${STATE_KEY_PREFIX}insideHandlesCanOpenDoorConfiguration`,
  lockTimeoutConfiguration: `${STATE_KEY_PREFIX}lockTimeoutConfiguration`,
  autoRelockTime: `${STATE_KEY_PREFIX}autoRelockTime`,
  holdAndReleaseTime: `${STATE_KEY_PREFIX}holdAndReleaseTime`,
  twistAssist: `${STATE_KEY_PREFIX}twistAssist`,
  blockToBlock: `${STATE_KEY_PREFIX}blockToBlock`
};
function getTransitionRemainingDuration(transition) {
  const remaining = Math.max(0, transition.durationMs - (Date.now() - transition.startTime));
  return new import_core.Duration(Math.ceil(remaining / 1e3), "seconds");
}
__name(getTransitionRemainingDuration, "getTransitionRemainingDuration");
function stopCurrentTransition(self) {
  const existing = self.state.get(StateKeys.transition);
  if (existing) {
    existing.timer.clear();
    self.state.set(StateKeys.currentMode, existing.targetMode);
    self.state.delete(StateKeys.transition);
    return { wasSupervised: existing.supervised };
  }
}
__name(stopCurrentTransition, "stopCurrentTransition");
function beginTransition(controller, self, receivedCC, targetMode, travelTime, supervised, onCompleteSupervised) {
  stopCurrentTransition(self);
  const currentMode = self.state.get(StateKeys.currentMode) ?? import_cc.DoorLockMode.Unsecured;
  if (currentMode === targetMode || travelTime === 0) {
    self.state.set(StateKeys.currentMode, targetMode);
    return 0;
  }
  const timer = (0, import_shared.setTimer)(async () => {
    self.state.set(StateKeys.currentMode, targetMode);
    self.state.delete(StateKeys.transition);
    if (supervised) {
      await onCompleteSupervised?.();
      return;
    }
    const cc = new import_DoorLockCC.DoorLockCCOperationReport({
      nodeId: controller.ownNodeId,
      currentMode: targetMode,
      outsideHandlesCanOpenDoor: [true, true, true, true],
      insideHandlesCanOpenDoor: [true, true, true, true],
      targetMode,
      duration: new import_core.Duration(0, "seconds")
    });
    await self.sendResponse(receivedCC, {
      action: "sendCC",
      cc
    });
  }, travelTime).unref();
  const transition = {
    targetMode,
    startTime: Date.now(),
    durationMs: travelTime,
    timer,
    supervised
  };
  self.state.set(StateKeys.transition, transition);
  return travelTime;
}
__name(beginTransition, "beginTransition");
const respondToDoorLockCapabilitiesGet = {
  handleCC(controller, self, receivedCC) {
    if (receivedCC instanceof import_DoorLockCC.DoorLockCCCapabilitiesGet) {
      const capabilities = {
        ...defaultCapabilities,
        ...self.getCCCapabilities(import_core.CommandClasses["Door Lock"], receivedCC.endpointIndex)
      };
      const cc = new import_DoorLockCC.DoorLockCCCapabilitiesReport({
        nodeId: controller.ownNodeId,
        supportedOperationTypes: capabilities.supportedOperationTypes,
        supportedDoorLockModes: capabilities.supportedDoorLockModes,
        supportedOutsideHandles: capabilities.supportedOutsideHandles,
        supportedInsideHandles: capabilities.supportedInsideHandles,
        doorSupported: capabilities.doorSupported,
        boltSupported: capabilities.boltSupported,
        latchSupported: capabilities.latchSupported,
        blockToBlockSupported: capabilities.blockToBlockSupported,
        twistAssistSupported: capabilities.twistAssistSupported,
        holdAndReleaseSupported: capabilities.holdAndReleaseSupported,
        autoRelockSupported: capabilities.autoRelockSupported
      });
      return { action: "sendCC", cc };
    }
  }
};
const respondToDoorLockOperationGet = {
  handleCC(controller, self, receivedCC) {
    if (receivedCC instanceof import_DoorLockCC.DoorLockCCOperationGet) {
      const transition = self.state.get(StateKeys.transition);
      let currentMode;
      let targetMode;
      let duration;
      if (transition) {
        currentMode = self.state.get(StateKeys.currentMode) ?? import_cc.DoorLockMode.Unsecured;
        targetMode = transition.targetMode;
        duration = getTransitionRemainingDuration(transition);
      } else {
        currentMode = self.state.get(StateKeys.currentMode) ?? import_cc.DoorLockMode.Unsecured;
        targetMode = currentMode;
        duration = new import_core.Duration(0, "seconds");
      }
      const cc = new import_DoorLockCC.DoorLockCCOperationReport({
        nodeId: controller.ownNodeId,
        currentMode,
        outsideHandlesCanOpenDoor: [true, true, true, true],
        insideHandlesCanOpenDoor: [true, true, true, true],
        targetMode,
        duration
      });
      return { action: "sendCC", cc };
    }
  }
};
const respondToDoorLockOperationSet = {
  handleCC(controller, self, receivedCC) {
    if (receivedCC instanceof import_DoorLockCC.DoorLockCCOperationSet) {
      const capabilities = {
        ...defaultCapabilities,
        ...self.getCCCapabilities(import_core.CommandClasses["Door Lock"], receivedCC.endpointIndex)
      };
      const supervised = receivedCC.isEncapsulatedWith(import_core.CommandClasses.Supervision);
      const durationMs = beginTransition(controller, self, receivedCC, receivedCC.mode, capabilities.travelTime, supervised, async () => self.sendResponse(receivedCC, {
        action: "ok"
      }));
      return {
        action: "ok",
        durationMs
      };
    }
  }
};
const respondToDoorLockConfigurationGet = {
  handleCC(controller, self, receivedCC) {
    if (receivedCC instanceof import_DoorLockCC.DoorLockCCConfigurationGet) {
      const operationType = self.state.get(StateKeys.operationType) ?? import_cc.DoorLockOperationType.Constant;
      const outsideHandlesCanOpenDoorConfiguration = self.state.get(StateKeys.outsideHandlesCanOpenDoorConfiguration) ?? [true, true, true, true];
      const insideHandlesCanOpenDoorConfiguration = self.state.get(StateKeys.insideHandlesCanOpenDoorConfiguration) ?? [true, true, true, true];
      const lockTimeoutConfiguration = self.state.get(StateKeys.lockTimeoutConfiguration);
      const autoRelockTime = self.state.get(StateKeys.autoRelockTime);
      const holdAndReleaseTime = self.state.get(StateKeys.holdAndReleaseTime);
      const twistAssist = self.state.get(StateKeys.twistAssist);
      const blockToBlock = self.state.get(StateKeys.blockToBlock);
      const cc = new import_DoorLockCC.DoorLockCCConfigurationReport({
        nodeId: controller.ownNodeId,
        operationType,
        outsideHandlesCanOpenDoorConfiguration,
        insideHandlesCanOpenDoorConfiguration,
        lockTimeoutConfiguration,
        autoRelockTime,
        holdAndReleaseTime,
        twistAssist,
        blockToBlock
      });
      return { action: "sendCC", cc };
    }
  }
};
const respondToDoorLockConfigurationSet = {
  handleCC(_controller, self, receivedCC) {
    if (receivedCC instanceof import_DoorLockCC.DoorLockCCConfigurationSet) {
      self.state.set(StateKeys.operationType, receivedCC.operationType);
      self.state.set(StateKeys.outsideHandlesCanOpenDoorConfiguration, receivedCC.outsideHandlesCanOpenDoorConfiguration);
      self.state.set(StateKeys.insideHandlesCanOpenDoorConfiguration, receivedCC.insideHandlesCanOpenDoorConfiguration);
      self.state.set(StateKeys.lockTimeoutConfiguration, receivedCC.lockTimeoutConfiguration);
      self.state.set(StateKeys.autoRelockTime, receivedCC.autoRelockTime);
      self.state.set(StateKeys.holdAndReleaseTime, receivedCC.holdAndReleaseTime);
      self.state.set(StateKeys.twistAssist, receivedCC.twistAssist);
      self.state.set(StateKeys.blockToBlock, receivedCC.blockToBlock);
      return { action: "ok" };
    }
  }
};
const DoorLockCCBehaviors = [
  respondToDoorLockCapabilitiesGet,
  respondToDoorLockOperationGet,
  respondToDoorLockOperationSet,
  respondToDoorLockConfigurationGet,
  respondToDoorLockConfigurationSet
];
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  DoorLockCCBehaviors
});
//# sourceMappingURL=DoorLock.js.map
