/**
 * Easy Chat Support - Capripio — front-end widget.
 * Vanilla JS, no dependencies.
 */
( function () {
	'use strict';

	if ( typeof CPECS_DATA === 'undefined' ) {
		return;
	}

	var STORAGE_UUID_KEY = 'cpecs_visitor_uuid';
	var STORAGE_CONV_KEY = 'cpecs_conversation_id';

	var state = {
		visitorUuid: null,
		conversationId: null,
		lastMessageId: 0,
		open: false,
		started: false,
		pollTimer: null,
		sending: false,
	};

	function qs( sel, ctx ) {
		return ( ctx || document ).querySelector( sel );
	}

	function el( tag, attrs, children ) {
		var node = document.createElement( tag );
		attrs = attrs || {};
		Object.keys( attrs ).forEach( function ( key ) {
			if ( key === 'class' ) {
				node.className = attrs[ key ];
			} else if ( key === 'html' ) {
				node.innerHTML = attrs[ key ];
			} else {
				node.setAttribute( key, attrs[ key ] );
			}
		} );
		( children || [] ).forEach( function ( child ) {
			if ( child ) {
				node.appendChild( child );
			}
		} );
		return node;
	}

	function getStoredUuid() {
		try {
			return window.localStorage.getItem( STORAGE_UUID_KEY ) || '';
		} catch ( e ) {
			return '';
		}
	}

	function setStoredUuid( uuid ) {
		try {
			window.localStorage.setItem( STORAGE_UUID_KEY, uuid );
		} catch ( e ) {}
	}

	function getStoredConversation() {
		try {
			return window.localStorage.getItem( STORAGE_CONV_KEY ) || '';
		} catch ( e ) {
			return '';
		}
	}

	function setStoredConversation( id ) {
		try {
			window.localStorage.setItem( STORAGE_CONV_KEY, id );
		} catch ( e ) {}
	}

	function apiFetch( path, options ) {
		options = options || {};
		var headers = options.headers || {};
		headers['Content-Type'] = 'application/json';
		headers['X-CPECS-Nonce'] = CPECS_DATA.nonce;

		return fetch( CPECS_DATA.restUrl + path, {
			method: options.method || 'GET',
			headers: headers,
			body: options.body ? JSON.stringify( options.body ) : undefined,
		} ).then( function ( res ) {
			return res.json().then( function ( data ) {
				if ( ! res.ok ) {
					throw data;
				}
				return data;
			} );
		} );
	}

	// -----------------------------------------------------------------
	// UI building
	// -----------------------------------------------------------------

	var root, launcher, panel, messagesEl, formEl, inputEl, preChatEl;
	var preChatFields = {};

	function markPreChatError( which ) {
		var f = preChatFields[ which ];
		if ( ! f ) return;
		f.input.classList.add( 'cpecs-input-error' );
		f.error.classList.add( 'cpecs-show' );
	}

	function build() {
		root = qs( '#cpecs-widget-root' );
		if ( ! root ) {
			return;
		}

		if ( CPECS_DATA.color ) {
			root.style.setProperty( '--cpecs-color', CPECS_DATA.color );
		}

		launcher = el( 'button', { class: 'cpecs-launcher', type: 'button', 'aria-label': CPECS_DATA.i18n.startPrompt }, [
			el( 'span', { class: 'cpecs-launcher-ring' } ),
			el( 'span', { class: 'cpecs-launcher-icon', html: chatIconSvg() } ),
		] );

		panel = el( 'div', { class: 'cpecs-panel', role: 'dialog', 'aria-label': CPECS_DATA.i18n.headerTitle }, [
			el( 'div', { class: 'cpecs-header' }, [
				el( 'div', { class: 'cpecs-header-row' }, [
					el( 'span', { class: 'cpecs-avatar', html: CPECS_DATA.companyLogo ? logoImgHtml() : avatarSvg() } ),
					el( 'div', { class: 'cpecs-header-text' }, [
						el( 'span', { class: 'cpecs-header-title', html: escapeHtml( CPECS_DATA.i18n.headerTitle ) } ),
						el( 'span', { class: 'cpecs-header-sub' }, [
							el( 'span', { class: 'cpecs-online-dot' } ),
							document.createTextNode( CPECS_DATA.i18n.onlineLabel ),
						] ),
					] ),
					el( 'button', { class: 'cpecs-close', type: 'button', 'aria-label': 'Close' }, [ el( 'span', { html: '&times;' } ) ] ),
				] ),
			] ),
			buildPreChat(),
			( messagesEl = el( 'div', { class: 'cpecs-messages' } ) ),
			( formEl = buildForm() ),
			buildFooter(),
		] );

		panel.querySelector( '.cpecs-close' ).addEventListener( 'click', togglePanel );
		launcher.addEventListener( 'click', togglePanel );

		root.appendChild( panel );
		root.appendChild( launcher );

		messagesEl.style.display = 'none';
		formEl.style.display = 'none';

		var storedUuid = getStoredUuid();
		var storedConv = getStoredConversation();
		if ( storedUuid && storedConv ) {
			state.visitorUuid = storedUuid;
			state.conversationId = parseInt( storedConv, 10 );
			state.started = true;
			showChatUI();
			loadExisting();
		}

		// Extension surface for the Pro plugin (optional; safe if unused).
		window.CPECSWidgetAPI = {
			apiFetch: apiFetch,
			el: el,
			escapeHtml: escapeHtml,
			getConversationId: function () { return state.conversationId; },
			getVisitorUuid: function () { return state.visitorUuid; },
			isOpen: function () { return state.open; },
		};
		document.dispatchEvent( new CustomEvent( 'cpecs:widget-built', {
			detail: { root: root, panel: panel, formEl: formEl, messagesEl: messagesEl, inputEl: inputEl },
		} ) );
	}

	function buildFooter() {
		if ( ! CPECS_DATA.branding || ! CPECS_DATA.branding.show ) {
			return null;
		}
		var link = el( 'a', {
			href: CPECS_DATA.branding.url,
			target: '_blank',
			rel: 'noopener',
			class: 'cpecs-branding-link',
		}, [ document.createTextNode( CPECS_DATA.i18n.poweredBy + ' ' + CPECS_DATA.branding.name ) ] );
		return el( 'div', { class: 'cpecs-branding' }, [ link ] );
	}

	function avatarSvg() {
		return '<svg viewBox="0 0 32 32" width="20" height="20" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="16" cy="16" r="16" fill="white" fill-opacity="0.18"/><path d="M9 13.5C9 10.5 11.7 8 15 8H17C20.3 8 23 10.5 23 13.5C23 16.5 20.3 19 17 19H14.8L11.2 21.5L11.9 18.4C10.1 17.4 9 15.6 9 13.5Z" fill="white"/></svg>';
	}

	function logoImgHtml() {
		return '<img src="' + escapeHtml( CPECS_DATA.companyLogo ) + '" alt="" style="width:100%;height:100%;object-fit:cover;border-radius:50%;" />';
	}

	function buildPreChat() {
		var nameInput = el( 'input', { type: 'text', class: 'cpecs-input', placeholder: CPECS_DATA.i18n.namePlaceholder, autocomplete: 'name' } );
		var nameError = el( 'span', { class: 'cpecs-field-error', html: CPECS_DATA.i18n.nameRequired } );
		var nameGroup = el( 'div', { class: 'cpecs-field-group' }, [ nameInput, nameError ] );

		var emailInput = el( 'input', { type: 'email', class: 'cpecs-input', placeholder: CPECS_DATA.i18n.emailPlaceholder, autocomplete: 'email' } );
		var emailError = el( 'span', { class: 'cpecs-field-error', html: CPECS_DATA.i18n.emailInvalid } );
		var emailGroup = el( 'div', { class: 'cpecs-field-group' }, [ emailInput, emailError ] );

		preChatFields.name = { input: nameInput, error: nameError };
		preChatFields.email = { input: emailInput, error: emailError };

		var startBtn = el( 'button', { type: 'button', class: 'cpecs-start-btn' }, [ document.createTextNode( CPECS_DATA.i18n.startButton ) ] );

		preChatEl = el( 'div', { class: 'cpecs-prechat' }, [ nameGroup, emailGroup, startBtn ] );

		function clearError( input, errorEl ) {
			input.classList.remove( 'cpecs-input-error' );
			errorEl.classList.remove( 'cpecs-show' );
		}
		function showError( input, errorEl ) {
			input.classList.add( 'cpecs-input-error' );
			errorEl.classList.add( 'cpecs-show' );
		}

		nameInput.addEventListener( 'input', function () { clearError( nameInput, nameError ); } );
		emailInput.addEventListener( 'input', function () { clearError( emailInput, emailError ); } );

		startBtn.addEventListener( 'click', function () {
			var name = nameInput.value.trim();
			var email = emailInput.value.trim();
			var valid = true;

			if ( ! name ) {
				showError( nameInput, nameError );
				valid = false;
			} else {
				clearError( nameInput, nameError );
			}

			// Email is optional, but if the visitor typed one it must be
			// a plausible address — checked here and re-checked server-side.
			if ( email && ! isValidEmail( email ) ) {
				showError( emailInput, emailError );
				valid = false;
			} else {
				clearError( emailInput, emailError );
			}

			if ( ! valid ) {
				return;
			}

			startConversation( name, email );
		} );

		return preChatEl;
	}

	function isValidEmail( value ) {
		// Practical, not fully RFC-5322-exhaustive — matches what the
		// server checks with is_email() closely enough for UX purposes.
		return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test( value );
	}

	function buildForm() {
		inputEl = el( 'input', { type: 'text', class: 'cpecs-msg-input', placeholder: CPECS_DATA.i18n.inputPlaceholder, autocomplete: 'off' } );
		var sendBtn = el( 'button', { type: 'submit', class: 'cpecs-send-btn', 'aria-label': CPECS_DATA.i18n.send }, [
			el( 'span', { html: sendIconSvg() } ),
		] );

		var form = el( 'form', { class: 'cpecs-form' }, [ inputEl, sendBtn ] );
		form.addEventListener( 'submit', function ( e ) {
			e.preventDefault();
			var val = inputEl.value.trim();
			if ( ! val ) {
				return;
			}
			sendMessage( val );
			inputEl.value = '';
		} );

		return form;
	}

	function sendIconSvg() {
		return '<svg viewBox="0 0 24 24" width="17" height="17" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M4 12L20 4L14 20L11 13L4 12Z" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round" stroke-linecap="round"/></svg>';
	}

	function chatIconSvg() {
		return '<svg viewBox="0 0 24 24" width="26" height="26" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M4 12C4 7.58172 7.58172 4 12 4C16.4183 4 20 7.58172 20 12C20 16.4183 16.4183 20 12 20C10.4531 20 9.00909 19.5637 7.78 18.8L4 20L5.2 16.22C4.4363 14.9909 4 13.5469 4 12Z" stroke="white" stroke-width="1.8" stroke-linejoin="round"/></svg>';
	}

	function escapeHtml( str ) {
		var div = document.createElement( 'div' );
		div.appendChild( document.createTextNode( str || '' ) );
		return div.innerHTML;
	}

	function togglePanel() {
		state.open = ! state.open;
		panel.classList.toggle( 'cpecs-open', state.open );
		launcher.classList.toggle( 'cpecs-hide', state.open );
		if ( state.open ) {
			scrollToBottom();
			document.dispatchEvent( new CustomEvent( 'cpecs:widget-open', { detail: { conversationId: state.conversationId } } ) );
		}
	}

	function showChatUI() {
		preChatEl.style.display = 'none';
		messagesEl.style.display = '';
		formEl.style.display = '';
	}

	// -----------------------------------------------------------------
	// Conversation flow
	// -----------------------------------------------------------------

	function startConversation( name, email ) {
		apiFetch( '/start', {
			method: 'POST',
			body: {
				visitor_uuid: getStoredUuid(),
				visitor_name: name,
				visitor_email: email,
				page_url: window.location.href,
				referrer: document.referrer,
			},
		} ).then( function ( data ) {
			state.visitorUuid = data.visitor_uuid;
			state.conversationId = data.conversation_id;
			state.started = true;

			setStoredUuid( data.visitor_uuid );
			setStoredConversation( data.conversation_id );

			showChatUI();
			renderMessages( data.messages );
			startPolling();
		} ).catch( function ( err ) {
			var code = err && err.code;
			if ( 'cpecs_missing_name' === code ) {
				markPreChatError( 'name' );
			} else if ( 'cpecs_invalid_email' === code ) {
				markPreChatError( 'email' );
			}
			// Otherwise fail silently in UI, avoid alarming visitors.
		} );
	}

	function loadExisting() {
		apiFetch( '/poll/' + state.conversationId + '?after=0&visitor_uuid=' + encodeURIComponent( state.visitorUuid ) ).then( function ( data ) {
			renderMessages( data.messages );
			startPolling();
		} ).catch( function () {
			// Conversation may have been deleted (retention) — reset local state.
			setStoredUuid( '' );
			setStoredConversation( '' );
			state.started = false;
			preChatEl.style.display = '';
			messagesEl.style.display = 'none';
			formEl.style.display = 'none';
		} );
	}

	function sendMessage( text ) {
		appendMessage( { sender_type: 'visitor', message: escapeHtml( text ), created_at: '' }, true );
		state.sending = true;
		apiFetch( '/message', {
			method: 'POST',
			body: {
				conversation_id: state.conversationId,
				visitor_uuid: state.visitorUuid,
				message: text,
			},
		} ).then( function ( data ) {
			// Mark this message as already-seen so the next poll doesn't
			// re-append the same message we already rendered optimistically.
			if ( data && data.message_id ) {
				state.lastMessageId = Math.max( state.lastMessageId, data.message_id );
			}
		} ).catch( function () {} ).then( function () {
			state.sending = false;
		} );
	}

	function startPolling() {
		if ( state.pollTimer ) {
			clearInterval( state.pollTimer );
		}
		state.pollTimer = setInterval( poll, CPECS_DATA.pollMs || 4000 );
	}

	function poll() {
		if ( ! state.conversationId || state.sending ) {
			return;
		}
		apiFetch( '/poll/' + state.conversationId + '?after=' + state.lastMessageId + '&visitor_uuid=' + encodeURIComponent( state.visitorUuid ) ).then( function ( data ) {
			if ( data.messages && data.messages.length ) {
				renderMessages( data.messages );
			}
		} ).catch( function () {} );
	}

	function renderMessages( messages ) {
		messages.forEach( function ( m ) {
			appendMessage( m, false );
		} );
	}

	function appendMessage( m, alreadyEscaped ) {
		if ( m.id ) {
			state.lastMessageId = Math.max( state.lastMessageId, m.id );
		}
		var bubble = el( 'div', { class: 'cpecs-bubble cpecs-' + ( m.sender_type === 'visitor' ? 'out' : 'in' ) }, [
			el( 'span', { class: 'cpecs-bubble-text', html: alreadyEscaped ? m.message : escapeHtml( m.message ) } ),
			el( 'span', { class: 'cpecs-bubble-time', html: formatTime( m.created_at ) } ),
		] );
		messagesEl.appendChild( bubble );
		scrollToBottom();
	}

	function formatTime( isoLike ) {
		var d = isoLike ? new Date( isoLike.replace( ' ', 'T' ) ) : new Date();
		if ( isNaN( d.getTime() ) ) {
			d = new Date();
		}
		var h = d.getHours();
		var m = d.getMinutes();
		var ampm = h >= 12 ? 'PM' : 'AM';
		h = h % 12;
		if ( h === 0 ) h = 12;
		return h + ':' + ( m < 10 ? '0' : '' ) + m + ' ' + ampm;
	}

	function scrollToBottom() {
		if ( messagesEl ) {
			messagesEl.scrollTop = messagesEl.scrollHeight;
		}
	}

	if ( document.readyState === 'loading' ) {
		document.addEventListener( 'DOMContentLoaded', build );
	} else {
		build();
	}
} )();
