import Connection from "./Connection.js";
import { z } from '/_/code/zod_4.2.1.js';

export default class ServerClient {
    connection;
    disabled = true;
    requestID = 1;
    pending = new Map();

    messageSchema = z.object({
        id: z.string(),
        op: z.string().optional(),
        msg: z.union([
            z.object({}).passthrough(), // allows any object
            z.array(z.any())            // allows any array
        ]).optional()
    })
    .superRefine((data, ctx) => {
        if (data.op !== "GET" && data.msg === undefined) {
            ctx.addIssue({
                code: z.ZodIssueCode.custom,
                path: ["msg"],
                message: "msg is required when operation is not GET"
            })
        }
    })
    .strict()

    constructor() {
        this.connection = new Connection(this.receive);
    }

    isOpen() {
        if(this.connection.checkOpen()) {
            return true;
        } else {
            return false;
        }
    }

    send(op, msg) {
        const id = (++this.requestID).toString();
        let toSend = {
            id: (++this.requestID).toString(),
            op: op,
            msg: msg
        }

        console.log(this.messageSchema.safeParse(toSend).error)
        if(!this.messageSchema.safeParse(toSend).success) throw new Error("ServerClient.send: ws message has incorrect format!")

        return new Promise(resolve => {
            this.pending.set(id, resolve);
            this.connection.send(JSON.stringify(toSend));
        });
    }

    receive = async (event) => {
        let msg = event.data;
        if(msg instanceof Blob) {
            msg = await msg.text()
        }
        msg = JSON.parse(msg);
        if (msg.id && this.pending.has(msg.id)) {
            this.pending.get(msg.id)(msg);
            this.pending.delete(msg.id);
            return;
        } else {
            this.onBroadcast(msg)
        }
    }

    onBroadcast(msg) {
        window.dispatchEvent(new CustomEvent("log", {
            detail: msg
        }));
    }
}