import { WebSocketWrapper } from "./shared.bundle.ts";

//interface ReconnectOptions {
//    reconnectInterval?: number; // Initial reconnect delay (ms)
//    maxReconnectInterval?: number; // Maximum delay (ms)
//    reconnectDecay?: number; // Exponential backoff multiplier
//    timeout?: number; // Connection timeout (ms)
//}
//
//class ReconnectingWebSocketClient {
//    private ws: WebSocket | null = null;
//    private url: string;
//    private reconnectInterval: number;
//    private maxReconnectInterval: number;
//    private reconnectDecay: number;
//    private timeout: number;
//    private forcedClose: boolean = false;
//    private onmessage?: (ev: MessageEvent) => any;
//
//    constructor(
//        url: string,
//        options: ReconnectOptions = {},
//    ) {
//        this.url = url;
//        this.reconnectInterval = options.reconnectInterval ?? 1000; // 1 second
//        this.maxReconnectInterval = options.maxReconnectInterval ?? 30000; // 30 seconds
//        this.reconnectDecay = options.reconnectDecay ?? 1.5;
//        this.timeout = options.timeout ?? 2000; // 2 seconds
//        this.connect();
//    }
//
//    private connect(isReconnect: boolean = false): void {
//        console.log(`Connecting to ${this.url}...`);
//
//        this.ws = new WebSocket(this.url);
//        let connectionTimeout = setTimeout(() => {
//            console.warn("Connection timeout, closing socket.");
//            this.ws?.close();
//        }, this.timeout);
//
//        this.ws.onopen = (event: Event) => {
//            clearTimeout(connectionTimeout);
//            console.log("WebSocket connected.");
//
//            if (this.onmessage) {
//                this.ws?.addEventListener("message", this.onmessage);
//            }
//
//            // On connection, send login credentials
//            // Optionally, if this is a reconnection, you could dispatch a custom event or handle state changes.
//        };
//
//        this.ws.onerror = (event: Event) => {
//            console.error("WebSocket error:", event);
//        };
//
//        this.ws.onclose = (event: CloseEvent) => {
//            clearTimeout(connectionTimeout);
//            console.log("WebSocket closed:", event.reason);
//            if (!this.forcedClose) {
//                // Schedule reconnection with exponential backoff
//                setTimeout(() => {
//                    this.reconnectInterval = Math.min(
//                        this.reconnectInterval * this.reconnectDecay,
//                        this.maxReconnectInterval,
//                    );
//                    this.connect(true);
//                }, this.reconnectInterval);
//            }
//        };
//    }
//
//    public onMessage(fn: (e: MessageEvent) => void) {
//        if (this.ws) {
//            this.ws.dispatchEvent;
//            this.ws.addEventListener("message", fn);
//        }
//
//        this.onmessage = fn;
//    }
//
//    public send(data: any): void {
//        if (this.ws && this.ws.readyState === WebSocket.OPEN) {
//            this.ws.send(data);
//        } else {
//            console.error("WebSocket is not open. Message not sent.");
//        }
//    }
//
//    public close(): void {
//        this.forcedClose = true;
//        this.ws?.close();
//    }
//}
//
//const ws = new ReconnectingWebSocketClient("/ws");
//
//ws.onMessage((e) => {
//    console.log(e.data);
//});
//
const pingBtn = document.getElementById("ping") as HTMLButtonElement;
const reconBtn = document.getElementById("reconnect") as HTMLButtonElement;
const infoDiv = document.getElementById("info") as HTMLDivElement;

pingBtn.onclick = async () => {
    await wrapper.ping();
};

reconBtn.onclick = async () => {
    console.log(await wrapper.connect());
};

const wrapper = new WebSocketWrapper(
    "api/admin/ws",
);

wrapper.onConnectInit = () => {
    infoDiv.innerText = "Connecting...";
};

wrapper.onConnectSucc = () => {
    infoDiv.innerText = "Connected!";
};

wrapper.onConnectFail = () => {
    infoDiv.innerText = "Failed to reconnect";
};

wrapper.onDisconnect = () => {
    infoDiv.innerText = "Connection lost";
};

wrapper.onMessage = (ev) => {
    console.log(ev.data);
};

await wrapper.connect();
