<script setup>
import { onBeforeUnmount, onMounted, ref, watch } from "vue";
import {} from "../../composables/hostAgent";
import { useHostAgentWs } from "../../composables/hostAgentWs";
const props = defineProps({
  withPhoto: { type: Boolean, required: false, default: false },
  reader: { type: [String, null], required: false, default: null },
  autoConnect: { type: Boolean, required: false, default: true },
  autoSubscribe: { type: Boolean, required: false, default: true },
  autoReconnect: { type: Boolean, required: false, default: false },
  reconnectDelayMs: { type: Number, required: false, default: 1e3 }
});
const emit = defineEmits(["connected", "disconnected", "subscribed", "unsubscribed", "inserted", "removed", "error", "message"]);
const host = useHostAgentWs();
const reconnectTimer = ref(null);
const mounted = ref(false);
const manuallyDisconnected = ref(false);
function clearReconnect() {
  if (reconnectTimer.value) {
    clearTimeout(reconnectTimer.value);
    reconnectTimer.value = null;
  }
}
function connectAndSubscribe() {
  manuallyDisconnected.value = false;
  host.connectIdCardWs();
}
function safeDisconnect() {
  manuallyDisconnected.value = true;
  clearReconnect();
  try {
    if (host.wsConnected.value) {
      try {
        host.unsubscribeIdCardWs();
      } catch {
      }
    }
  } catch {
  }
  host.disconnectIdCardWs();
}
const off = host.onIdCardWsEvent((ev) => {
  if (ev.type === "open") {
    emit("connected");
    if (props.autoSubscribe) {
      try {
        host.subscribeIdCardWs({ reader: props.reader ?? null, withPhoto: props.withPhoto });
      } catch (e) {
        emit("error", e);
      }
    }
    return;
  }
  if (ev.type === "close") {
    emit("disconnected", { code: ev.code, reason: ev.reason });
    if (props.autoReconnect && mounted.value && !manuallyDisconnected.value) {
      clearReconnect();
      reconnectTimer.value = setTimeout(() => {
        try {
          connectAndSubscribe();
        } catch (e) {
          emit("error", e);
        }
      }, props.reconnectDelayMs);
    }
    return;
  }
  if (ev.type === "error") {
    emit("error", ev.error);
    return;
  }
  if (ev.type === "message") {
    const msg = ev.data;
    emit("message", msg);
    switch (msg.type) {
      case "monitor.subscribed":
        if (msg.ok) emit("subscribed", { reader: msg.reader ?? null, withPhoto: !!msg.withPhoto });
        break;
      case "monitor.unsubscribed":
        emit("unsubscribed");
        break;
      case "card.inserted":
        emit("inserted", msg.payload);
        break;
      case "card.removed":
        emit("removed");
        break;
      case "card.error":
      case "error":
        emit("error", msg);
        break;
    }
  }
});
onMounted(() => {
  mounted.value = true;
  if (props.autoConnect) connectAndSubscribe();
});
onBeforeUnmount(() => {
  mounted.value = false;
  try {
    off?.();
  } catch {
  }
  safeDisconnect();
});
watch(
  () => props.reader,
  (r) => {
    if (!mounted.value) return;
    if (!host.wsConnected.value) return;
    if (!host.wsSubscribed.value) return;
    try {
      host.switchReaderIdCardWs(r ?? null);
    } catch (e) {
      emit("error", e);
    }
  }
);
watch(
  () => props.withPhoto,
  (withPhoto) => {
    if (!mounted.value) return;
    if (!host.wsConnected.value) return;
    try {
      if (host.wsSubscribed.value) {
        host.unsubscribeIdCardWs();
      }
    } catch {
    }
    setTimeout(() => {
      try {
        if (host.wsConnected.value) {
          host.subscribeIdCardWs({ reader: props.reader ?? null, withPhoto });
        }
      } catch (e) {
        emit("error", e);
      }
    }, 0);
  }
);
</script>

<template>
  <!-- Intentionally blank (headless component) -->
</template>
