import { writable } from "svelte/store";
import type { ConnectionState, ConnectionType } from "./types";
import {
  ConnectEvent,
  HeartbeatEvent,
  NiimbotBluetoothClient,
  NiimbotSerialClient,
  // PacketParsedEvent,
  RawPacketReceivedEvent,
  RawPacketSentEvent,
  Utils,
  type HeartbeatData,
  type NiimbotAbstractClient,
  type PrinterConfig,
} from "@mmote/niimbluelib";

export const connectionState = writable<ConnectionState>("disconnected");
export const connectedPrinterName = writable<string>("");
export const printerClient = writable<NiimbotAbstractClient>();
export const heartbeatData = writable<HeartbeatData>();
export const printerConfig = writable<PrinterConfig>();

export const initClient = (connectionType: ConnectionType) => {
  printerClient.update((prevClient: NiimbotAbstractClient) => {
    let newClient: NiimbotAbstractClient = prevClient;

    if (
      prevClient === undefined ||
      (connectionType !== "bluetooth" && prevClient instanceof NiimbotBluetoothClient) ||
      (connectionType !== "serial" && prevClient instanceof NiimbotSerialClient)
    ) {
      if (prevClient !== undefined) {
        prevClient.disconnect();
      }
      if (connectionType === "bluetooth") {
        console.log("new NiimbotBluetoothClient");
        newClient = new NiimbotBluetoothClient();
      } else {
        console.log("new NiimbotSerialClient");
        newClient = new NiimbotSerialClient();
      }

      newClient.addEventListener("rawpacketsent", (e: RawPacketSentEvent) => {
        console.log(`>> ${Utils.bufToHex(e.data)}`);
      });

      newClient.addEventListener("rawpacketreceived", (e: RawPacketReceivedEvent) => {
        console.log(`<< ${Utils.bufToHex(e.data)}`);
      });

      newClient.addEventListener("connect", (e: ConnectEvent) => {
        console.log("onConnect");
        connectionState.set("connected");
        connectedPrinterName.set(e.info.deviceName ?? "unknown");
        printerConfig.set(newClient.getPrinterInfo());
      });

      newClient.addEventListener("disconnect", () => {
        console.log("onDisconnect");
        connectionState.set("disconnected");
        connectedPrinterName.set("");
        printerConfig.set({});
      });

      newClient.addEventListener("heartbeat", (e: HeartbeatEvent) => {
        heartbeatData.set(e.data);
      });
    }

    return newClient;
  });
};