const body = document.body;
const widgetUrl = new URL("https:\/\/integrations.winespot.ai\/chat\/widget.php?pid=8801a9ec-7bde-4f28-bdf9-5eca765ba06f&v=37ae9bf0ec");
const hostOrigin = window.location.origin;
widgetUrl.searchParams.set('host_origin', hostOrigin);
const widgetOrigin = widgetUrl.origin;
const winespot = document.createElement('iframe');
winespot.id = 'winespot';
winespot.sandbox = 'allow-scripts allow-same-origin allow-popups';
winespot.allow = 'clipboard-write';
winespot.src = widgetUrl.toString();
winespot.style.display = 'none';
body.appendChild(winespot);
const medal = document.createElement('iframe');
medal.id = 'wsf_medal';
medal.sandbox = 'allow-scripts allow-same-origin';
medal.style.display = 'none';
medal.setAttribute('srcdoc','
');
body.appendChild(medal);
medal.setAttribute('style','display:block');
body.insertAdjacentHTML('beforeend',`
`);
const capabilities = {
state: true,
resize: true,
openLink: true,
viewport: true,
medalClick: true
};
const utoken = new URLSearchParams(window.location.search).get('utoken') || '';
const sessionId = globalThis.crypto?.randomUUID ? globalThis.crypto.randomUUID() : 'ws_' + Math.random().toString(36).slice(2) + Date.now().toString(36);
let handshakeReady = false;
let lastViewport = '';
let currentState = 'closed';
const allowedProtocols = ['http:', 'https:'];
const sendToWidget = (type, payload = {}) => {
const target = winespot.contentWindow;
if(!target) return;
target.postMessage({ type, payload }, widgetOrigin);
};
const updateMedalIcon = (isOpen) => {
if(isOpen) {
body.classList.add('-chatOpened');
} else {
body.classList.remove('-chatOpened');
}
try {
const medalDoc = medal.contentDocument;
const backIcon = medalDoc?.getElementById('back-icon');
if(backIcon) {
if(isOpen) {
backIcon.classList.add('active');
} else {
backIcon.classList.remove('active');
}
}
} catch (err) {}
};
const setState = state => {
const nextState = state || 'closed';
if(currentState === nextState) return;
currentState = nextState;
if(nextState === 'closed') {
winespot.style.display = 'none';
winespot.classList.remove('-opened','-hello');
medal.classList.remove('-chatOpened');
updateMedalIcon(false);
return;
}
winespot.style.display = 'block';
if(nextState === 'hello') {
winespot.classList.add('-hello');
winespot.classList.remove('-opened');
medal.classList.remove('-chatOpened');
updateMedalIcon(false);
applyResize();
return;
}
winespot.classList.add('-opened');
winespot.classList.remove('-hello');
medal.classList.add('-chatOpened');
updateMedalIcon(true);
applyResize();
};
const getViewportType = () => {
const width = window.innerWidth;
if(width < 450) {
return 'isMobile';
}
if(width < 768) {
return 'isTablet';
}
if(window.innerHeight < 850) {
return 'isLaptop';
}
return '';
};
const broadcastViewport = (force = false) => {
const nextType = getViewportType();
if(!force && nextType === lastViewport) return;
lastViewport = nextType;
if(handshakeReady) {
sendToWidget('WS:VIEWPORT', { type: nextType });
}
};
let requestedHeight = 700;
const getWidgetBottom = () => {
if(window.innerWidth < 450) return 0;
if(winespot.classList.contains('-hello')) return 90;
return 116;
};
const applyResize = height => {
const parsed = parseInt(height, 10);
if(Number.isFinite(parsed)) {
requestedHeight = parsed;
}
const targetHeight = winespot.classList.contains('-hello') ? 180 : requestedHeight;
const topGap = 20;
const maxHeight = Math.max(0, window.innerHeight - getWidgetBottom() - topGap);
const minHeight = 180;
const finalHeight = maxHeight < minHeight
? maxHeight
: Math.max(minHeight, Math.min(targetHeight, maxHeight));
winespot.style.height = Math.max(0, Math.floor(finalHeight)) + 'px';
};
const openLink = href => {
if(!href) return;
try {
const url = new URL(href, window.location.origin);
if(!allowedProtocols.includes(url.protocol)) return;
window.open(url.toString(), '_blank');
} catch (err) {}
};
const handleHello = payload => {
const nonce = payload?.nonce;
handshakeReady = false;
sendToWidget('WS:HELLO_ACK', {
sessionId,
nonce,
utoken,
capabilities,
url: window.location.href,
});
handshakeReady = true;
broadcastViewport(true);
};
const handleMessage = event => {
if(event.origin !== widgetOrigin || event.source !== winespot.contentWindow) return;
const { type, payload = {}, sessionId: messageSessionId } = event.data || {};
if(type === 'WS:HELLO') {
handleHello(payload);
return;
}
if(!handshakeReady || messageSessionId !== sessionId) return;
if(type === 'WS:STATE') {
setState(payload?.state);
} else if(type === 'WS:RESIZE') {
applyResize(payload?.height);
} else if(type === 'WS:OPEN_LINK') {
openLink(payload?.href);
} else if(type === 'WS:CHANGE_LINK') {
window.history.replaceState({ path: payload?.url, type: 'clean' }, '', payload?.url);
}
};
let resizeTimeout;
window.addEventListener('resize', () => {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(() => {
broadcastViewport();
applyResize();
}, 150);
});
medal.addEventListener('load', () => {
try {
const medalDoc = medal.contentDocument;
const medalBody = medalDoc?.body;
if(medalBody) {
medalBody.classList.add('-loaded');
}
const medalEl = medalDoc?.getElementById('ws_medal');
if(medalEl) {
medalEl.addEventListener('click', () => {
if(!handshakeReady) return;
sendToWidget('WS:MEDAL_CLICK', {});
});
}
if(currentState === 'open') {
body.classList.add('-chatOpened');
const backIcon = medalDoc?.getElementById('back-icon');
if(backIcon) {
backIcon.classList.add('active');
}
}
} catch (err) {}
});
window.addEventListener('message', handleMessage);
setState('closed');