import {
   type ICollectionRef,
   type IDocumentRef,
   UpdateTypes,
} from "@rtdb2/sdk";
import { nanoid } from "nanoid";
import { Peer } from "peerjs/lib/peer";
import {
   collectionToStore,
   Sessions,
   type IMember,
   type IMessage,
   type ISession,
} from "./db";

import type { Readable } from "svelte/store";
import { Signal } from "@hibas123/utils";

export class Session {
   #client_id = nanoid(22);
   #peer: Peer;

   #session: IDocumentRef<ISession>;
   #members: ICollectionRef<IMember>;
   #messages: ICollectionRef<IMessage>;
   #self: IDocumentRef<IMember>;

   #name: string;
   #iv: any;

   #closeSignal = new Signal();

   members: Readable<(IMember & { $id: string })[]>;
   messages: Readable<(IMessage & { $id: string })[]>;

   get name() {
      return this.#name;
   }

   set name(value) {
      this.#name = value;
      this.#self.update({ name: UpdateTypes.Value(value) });
   }

   constructor(id: string, name: string) {
      this.#name = name;

      this.#peer = new Peer(this.#client_id, {
         host: window.location.hostname,
         port: window.location.port as any,
         path: "/peerjs",
         config: {},
      });

      this.#session = Sessions.doc(id);
      this.#members = this.#session.collection("members");
      this.#messages = this.#session.collection("messages");
      this.#self = this.#members.doc(this.#client_id);
      this.members = collectionToStore(this.#members);
      this.messages = collectionToStore(this.#messages);

      this.registerSelf();
      this.#iv = setInterval(() => this.tick(), 5000);
   }

   tick() {
      this.#self.update({ lastActive: UpdateTypes.Value(Date.now()) });
   }

   registerSelf() {
      this.#self.set({
         name: this.#name,
         lastActive: Date.now(),
         offline: false,
      });
   }

   close() {
      this.#closeSignal.sendSignal();
      clearInterval(this.#iv);
      this.#self.update({ offline: UpdateTypes.Value(true) });
      this.#peer.destroy();
   }
}

let bitrate = new URL(window.location.href).searchParams.get("br") || 50000;

function bitrateTransform(sdp: string) {
   var arr = sdp.split("\r\n");
   arr.forEach((str, i) => {
      if (/^a=fmtp:\d*/.test(str)) {
         console.log("found fmtp");
         arr[i] =
            str +
            `;x-google-max-bitrate=${bitrate};x-google-min-bitrate=0;x-google-start-bitrate=12000`;
      } else if (/^a=mid:(1|video)/.test(str)) {
         console.log("found mid");
         arr[i] += "\r\nb=AS:" + bitrate;
      }
   });

   let res = arr.join("\r\n");
   console.log(sdp, res);
   return res;
}
