/**
 * Zebra 프린터 Web Bluetooth LE 연동
 * Chrome/Edge (Chromium) 에서만 지원. BLE로 ZPL 전송 (512바이트 청크)
 * 참고: https://developer.zebra.com/content/printing-webapp-using-webbluetooth
 */

const ZEBRA_BLE_SERVICE_UUID = "38eb4a80-c570-11e3-9507-0002a5d5c51b";
const ZEBRA_BLE_CHAR_UUID = "38eb4a82-c570-11e3-9507-0002a5d5c51b";
const CHUNK_SIZE = 512;
const CHUNK_DELAY_MS = 20;

export function isWebBluetoothSupported(): boolean {
  if (typeof window === "undefined") return false;
  return !!(navigator.bluetooth && navigator.bluetooth.requestDevice);
}

/** 지원 브라우저 안내 문구 */
export function getUnsupportedMessage(): string {
  if (!isWebBluetoothSupported()) {
    return "이 브라우저는 Web Bluetooth를 지원하지 않습니다. Chrome 또는 Edge(Chromium)에서 열어주세요. HTTPS 또는 localhost 필요.";
  }
  return "";
}

export interface ZebraPrintResult {
  success: boolean;
  message: string;
}

/**
 * Zebra 프린터를 BLE로 선택·연결 후 ZPL 데이터 전송
 * - 사용자에게 블루투스 기기 선택 창이 뜸 (Zebra 프린터 BLE 선택)
 * - ZPL을 512바이트 단위로 나누어 순차 전송
 */
export async function printZPLToZebraBLE(zpl: string): Promise<ZebraPrintResult> {
  if (!isWebBluetoothSupported()) {
    return {
      success: false,
      message: "Web Bluetooth를 지원하지 않는 브라우저입니다. Chrome 또는 Edge에서 시도해주세요.",
    };
  }

  let device: BluetoothDevice | null = null;
  let server: BluetoothRemoteGATTServer | null = null;

  try {
    // 1) 서비스 UUID로만 필터 시 Android에서 Zebra가 광고하지 않으면 목록에 안 나옴.
    // 2) acceptAllDevices + optionalServices 로 모든 BLE 기기 표시 후, 연결해 Zebra 서비스 사용.
    const useAcceptAll =
      typeof navigator !== "undefined" &&
      /Android/i.test(navigator.userAgent);

    if (useAcceptAll) {
      device = await navigator.bluetooth.requestDevice({
        acceptAllDevices: true,
        optionalServices: [ZEBRA_BLE_SERVICE_UUID],
      });
    } else {
      device = await navigator.bluetooth.requestDevice({
        filters: [{ services: [ZEBRA_BLE_SERVICE_UUID] }],
        optionalServices: [ZEBRA_BLE_SERVICE_UUID],
      });
    }

    if (!device) {
      return { success: false, message: "프린터를 선택하지 않았습니다." };
    }

    server = await device.gatt!.connect();
    let service: BluetoothRemoteGATTService;
    try {
      service = await server.getPrimaryService(ZEBRA_BLE_SERVICE_UUID);
    } catch {
      return {
        success: false,
        message:
          "선택한 기기는 Zebra 프린터가 아니거나 BLE 인쇄를 지원하지 않습니다. 'ZD421' 등 Zebra 프린터를 선택해 주세요.",
      };
    }
    const characteristic = await service.getCharacteristic(ZEBRA_BLE_CHAR_UUID);

    const encoder = new TextEncoder();
    const data = encoder.encode(zpl);
    const totalChunks = Math.ceil(data.length / CHUNK_SIZE);

    for (let i = 0; i < totalChunks; i++) {
      const start = i * CHUNK_SIZE;
      const end = Math.min(start + CHUNK_SIZE, data.length);
      const chunk = data.slice(start, end);
      await characteristic.writeValue(chunk);
      if (i < totalChunks - 1 && CHUNK_DELAY_MS > 0) {
        await new Promise((r) => setTimeout(r, CHUNK_DELAY_MS));
      }
    }

    return { success: true, message: "Zebra 프린터로 전송했습니다." };
  } catch (err: unknown) {
    const e = err as Error & { name?: string };
    if (e.name === "NotFoundError") {
      return { success: false, message: "Zebra 프린터(BLE)를 찾을 수 없습니다. 프린터 전원과 블루투스 설정을 확인하세요." };
    }
    if (e.name === "NotAllowedError") {
      return { success: false, message: "블루투스 연결이 거부되었습니다." };
    }
    return {
      success: false,
      message: e.message || "Zebra BLE 출력 중 오류가 발생했습니다.",
    };
  } finally {
    if (server && device?.gatt?.connected) {
      try {
        device.gatt.disconnect();
      } catch {
        // ignore
      }
    }
  }
}
