import { ref, type Ref } from "vue";
import { isInsideContainer, getHostProvider } from "@parity/product-sdk-host";
import { createClient, type PolkadotClient } from "polkadot-api";

// Paseo / Summitnet Asset Hub — same as host-playground / blocktimeshost. Blocks
// every ~6s so the rolling beacon feel stays lively. Swap if the deck ever
// targets a different network.
const CHAIN_GENESIS =
  "0xf388dc6d6cdf6fb77eac3c4a91f31bc0c8642b142f1a757512ab7849f9f70660" as const;

const MAX_BEACONS = 8;

export interface Beacon {
  number: number;
  hash: string; // full 0x… hash
  receivedAt: number; // Date.now() at arrival
}

// Module-level singletons. Slidev keeps the app mounted for the whole talk,
// so we don't bother reference-counting teardown — first consumer starts the
// stream, everyone shares the same reactive list.
const beacons: Ref<Beacon[]> = ref([]);
const connected = ref(false);

let started = false;
let client: PolkadotClient | null = null;

async function start() {
  if (started) return;
  started = true;

  try {
    const inside = await isInsideContainer();
    if (!inside) {
      console.warn("[beacons] not inside host container — no real blocks");
      return;
    }
    const provider = await getHostProvider(CHAIN_GENESIS);
    if (!provider) {
      console.warn("[beacons] getHostProvider returned null");
      return;
    }
    client = createClient(provider);
    client.bestBlocks$.subscribe({
      next(blocks) {
        const best = blocks[0];
        if (!best) return;
        if (beacons.value[0]?.hash === best.hash) return;
        beacons.value = [
          { number: best.number, hash: best.hash, receivedAt: Date.now() },
          ...beacons.value.filter((b) => b.hash !== best.hash),
        ].slice(0, MAX_BEACONS);
        connected.value = true;
      },
      error(err) {
        console.error("[beacons] stream error", err);
        connected.value = false;
      },
      complete() {
        connected.value = false;
      },
    });
  } catch (err) {
    console.error("[beacons] start failed", err);
  }
}

export function useBlockBeacons() {
  // Fire-and-forget: caller doesn't need to await — the ref fills as blocks land.
  void start();
  return { beacons, connected };
}
