/**
 * GoValid Smart Verify Widget for WordPress.
 *
 * Supports multiple instances (inline shortcode + floating FAB).
 * Uses jsQR for client-side QR decoding with server-side fallback.
 *
 * @package GoValid_QR
 */
( function () {
	'use strict';

	var cfg  = window.govalidVerify || {};
	var base = cfg.baseUrl || 'https://my.govalid.org';
	var i18n = cfg.i18n || {};

	/* ── Floating FAB toggle ─────────────────────────────── */
	function initFloatingWidget() {
		var toggle = document.getElementById( 'govalid-sv-toggle' );
		var panel  = document.getElementById( 'govalid-sv-panel' );
		var close  = document.getElementById( 'govalid-sv-close' );
		if ( ! toggle || ! panel ) return;

		toggle.addEventListener( 'click', function () {
			panel.classList.toggle( 'open' );
			toggle.classList.toggle( 'active' );
		} );

		if ( close ) {
			close.addEventListener( 'click', function () {
				panel.classList.remove( 'open' );
				toggle.classList.remove( 'active' );
				stopAllCameras();
			} );
		}

		document.addEventListener( 'click', function ( e ) {
			var widget = document.getElementById( 'govalid-smart-verify-widget' );
			if ( widget && panel.classList.contains( 'open' ) && ! widget.contains( e.target ) ) {
				panel.classList.remove( 'open' );
				toggle.classList.remove( 'active' );
				stopAllCameras();
			}
		} );
	}

	/* ── Per-panel initializer (works for inline + floating) ── */
	function initPanel( panel ) {
		var tabs         = panel.querySelectorAll( '.govalid-sv-tab' );
		var searchBtn    = panel.querySelector( '.govalid-sv-search-btn' );
		var qrInput      = panel.querySelector( '.govalid-sv-qr-input' );
		var dropzone     = panel.querySelector( '.govalid-sv-dropzone' );
		var fileInput    = panel.querySelector( '.govalid-sv-file-input' );
		var preview      = panel.querySelector( '.govalid-sv-preview' );
		var previewImg   = panel.querySelector( '.govalid-sv-preview-img' );
		var clearBtn     = panel.querySelector( '.govalid-sv-clear-preview' );
		var resultsDiv   = panel.querySelector( '.govalid-sv-results' );
		var loadingDiv   = panel.querySelector( '.govalid-sv-loading' );
		var resultContent = panel.querySelector( '.govalid-sv-result-content' );

		var cameraVideo  = panel.querySelector( '.govalid-sv-camera-video' );
		var cameraCanvas = panel.querySelector( '.govalid-sv-camera-canvas' );
		var cameraStart  = panel.querySelector( '.govalid-sv-camera-start' );
		var cameraStop   = panel.querySelector( '.govalid-sv-camera-stop' );
		var cameraStatus = panel.querySelector( '.govalid-sv-camera-status' );

		var cameraStream  = null;
		var scanInterval  = null;

		/* Tabs */
		tabs.forEach( function ( tab ) {
			tab.addEventListener( 'click', function () {
				var id = this.dataset.tab;
				tabs.forEach( function ( t ) { t.classList.toggle( 'active', t.dataset.tab === id ); } );
				panel.querySelectorAll( '.govalid-sv-tab-content' ).forEach( function ( c ) {
					c.classList.toggle( 'active', c.getAttribute( 'data-tab-content' ) === id );
				} );
				hideResults();
				if ( id !== 'camera' ) stopCamera();
			} );
		} );

		/* QR ID search */
		if ( searchBtn ) searchBtn.addEventListener( 'click', searchByQRId );
		if ( qrInput ) qrInput.addEventListener( 'keypress', function ( e ) { if ( e.key === 'Enter' ) searchByQRId(); } );

		/* Camera */
		if ( cameraStart ) cameraStart.addEventListener( 'click', startCamera );
		if ( cameraStop )  cameraStop.addEventListener( 'click', stopCamera );

		/* File upload */
		if ( dropzone && fileInput ) {
			dropzone.addEventListener( 'click', function () { fileInput.click(); } );
			fileInput.addEventListener( 'change', function ( e ) { if ( e.target.files[0] ) processFile( e.target.files[0] ); } );
			dropzone.addEventListener( 'dragover', function ( e ) { e.preventDefault(); dropzone.classList.add( 'dragover' ); } );
			dropzone.addEventListener( 'dragleave', function ( e ) { e.preventDefault(); dropzone.classList.remove( 'dragover' ); } );
			dropzone.addEventListener( 'drop', function ( e ) {
				e.preventDefault();
				dropzone.classList.remove( 'dragover' );
				var f = e.dataTransfer.files[0];
				if ( f && f.type.startsWith( 'image/' ) ) processFile( f );
			} );
		}

		if ( clearBtn ) {
			clearBtn.addEventListener( 'click', function () {
				preview.style.display = 'none';
				dropzone.style.display = 'flex';
				previewImg.src = '';
				fileInput.value = '';
				hideResults();
			} );
		}

		/* ── Camera ─────────────────────────────────────── */
		function startCamera() {
			if ( ! navigator.mediaDevices || ! navigator.mediaDevices.getUserMedia ) {
				cameraStatus.textContent = i18n.camera_unsupported || 'Camera not supported';
				cameraStatus.style.color = '#c53030';
				return;
			}
			cameraStatus.textContent = i18n.camera_starting || 'Starting camera...';
			cameraStatus.style.color = '#666';

			navigator.mediaDevices.getUserMedia( { video: { facingMode: 'environment' } } )
				.then( function ( stream ) {
					cameraStream = stream;
					cameraVideo.srcObject = stream;
					cameraVideo.play();
					cameraStart.style.display = 'none';
					cameraStop.style.display = 'inline-flex';
					cameraStatus.textContent = i18n.scanning || 'Scanning for QR code...';
					cameraStatus.style.color = '#667eea';
					scanInterval = setInterval( scanCameraFrame, 300 );
				} )
				.catch( function () {
					cameraStatus.textContent = i18n.camera_denied || 'Camera access denied';
					cameraStatus.style.color = '#c53030';
				} );
		}

		function stopCamera() {
			if ( scanInterval ) { clearInterval( scanInterval ); scanInterval = null; }
			if ( cameraStream ) {
				cameraStream.getTracks().forEach( function ( t ) { t.stop(); } );
				cameraStream = null;
			}
			if ( cameraVideo ) cameraVideo.srcObject = null;
			if ( cameraStart ) cameraStart.style.display = 'inline-flex';
			if ( cameraStop )  cameraStop.style.display = 'none';
			if ( cameraStatus ) cameraStatus.textContent = '';
		}

		// Expose for global stopAllCameras.
		panel._stopCamera = stopCamera;

		function scanCameraFrame() {
			if ( ! cameraVideo.videoWidth || ! cameraVideo.videoHeight ) return;
			var ctx = cameraCanvas.getContext( '2d' );
			cameraCanvas.width  = cameraVideo.videoWidth;
			cameraCanvas.height = cameraVideo.videoHeight;
			ctx.drawImage( cameraVideo, 0, 0 );
			var imgData = ctx.getImageData( 0, 0, cameraCanvas.width, cameraCanvas.height );

			if ( typeof jsQR === 'undefined' ) return;

			var code = jsQR( imgData.data, imgData.width, imgData.height, { inversionAttempts: 'dontInvert' } );
			if ( ! code ) code = jsQR( imgData.data, imgData.width, imgData.height, { inversionAttempts: 'attemptBoth' } );

			if ( code && code.data ) {
				stopCamera();
				cameraStatus.textContent = i18n.qr_detected || 'QR code detected!';
				cameraStatus.style.color = '#38a169';
				if ( isGoValidQR( code.data ) ) {
					verifyGoValidQR( code.data );
				} else {
					showError( i18n.not_govalid || 'Not a GoValid QR code' );
				}
			}
		}

		/* ── Search by QR ID ────────────────────────────── */
		function searchByQRId() {
			var qrId = qrInput.value.trim();
			if ( ! qrId ) { showError( i18n.enter_qr_id || 'Please enter a QR ID' ); return; }
			showLoading();
			fetch( base + '/qr_codes/api/v1/qr/lookup/?formatted_uuid=' + encodeURIComponent( qrId ) )
				.then( function ( r ) { return r.json(); } )
				.then( function ( data ) {
					if ( data.success && data.data ) showQRDetails( data.data );
					else showError( data.message || i18n.not_found || 'QR code not found' );
				} )
				.catch( function () { showError( i18n.failed_search || 'Failed to search' ); } );
		}

		/* ── File upload ────────────────────────────────── */
		function processFile( file ) {
			var reader = new FileReader();
			reader.onload = function ( e ) {
				previewImg.src = e.target.result;
				preview.style.display = 'block';
				dropzone.style.display = 'none';
				scanImage( e.target.result );
			};
			reader.readAsDataURL( file );
		}

		function scanImage( src ) {
			showLoading();
			var img = new Image();
			img.onload = function () {
				var canvas = document.createElement( 'canvas' );
				var ctx    = canvas.getContext( '2d' );
				canvas.width = img.width; canvas.height = img.height;
				ctx.drawImage( img, 0, 0 );
				var imgData = ctx.getImageData( 0, 0, canvas.width, canvas.height );

				var code = null;
				if ( typeof jsQR !== 'undefined' ) {
					code = jsQR( imgData.data, imgData.width, imgData.height, { inversionAttempts: 'dontInvert' } );
					if ( ! code ) code = jsQR( imgData.data, imgData.width, imgData.height, { inversionAttempts: 'attemptBoth' } );
				}

				if ( code && code.data ) {
					if ( isGoValidQR( code.data ) ) verifyGoValidQR( code.data );
					else showError( i18n.not_govalid || 'Not a GoValid QR code' );
				} else {
					decodeServerSide( src );
				}
			};
			img.onerror = function () { showError( i18n.failed_load_image || 'Failed to load image' ); };
			img.src = src;
		}

		function decodeServerSide( src ) {
			var b64 = src.includes( ',' ) ? src.split( ',' )[1] : src;
			fetch( base + '/api/v1/ojs/decode-qr-image/', {
				method: 'POST',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify( { image_base64: b64 } ),
			} )
			.then( function ( r ) { return r.json(); } )
			.then( function ( res ) {
				var d = res.content || res;
				if ( d.success && d.qr_data ) {
					if ( d.is_govalid_qr ) verifyGoValidQR( d.qr_data );
					else showError( i18n.not_govalid || 'Not a GoValid QR code' );
				} else {
					showError( d.error || i18n.no_qr_detected || 'No QR code detected' );
				}
			} )
			.catch( function () { showError( i18n.failed_decode || 'Failed to decode' ); } );
		}

		/* ── GoValid verification logic ─────────────────── */
		function isGoValidQR( data ) {
			if ( data.includes( 'govalid.org/qr_codes/verify-scan/' ) ) return true;
			if ( data.includes( 'govalid.org/v/' ) || data.includes( 'govalid.org/verify/' ) || data.includes( 'govalid.org/qr/' ) ) return true;
			// Recognize this WordPress site's own /v/ URLs.
			var siteHost = window.location.hostname;
			if ( siteHost && data.includes( siteHost + '/v/' ) ) return true;
			if ( /^[A-Z0-9]{4}-[A-Z0-9]{2}-[a-zA-Z0-9]+$/i.test( data ) ) return true;
			return false;
		}

		function verifyGoValidQR( data ) {
			showLoading();

			// Signed URL pattern /v/TOKEN (GoValid domain or this site's domain).
			var siteHost = window.location.hostname.replace( /\./g, '\\.' );
			var signedMatch = data.match( /govalid\.org\/v\/([A-Za-z0-9_.-]+)/ )
				|| data.match( new RegExp( siteHost + '\\/v\\/([A-Za-z0-9_.-]+)' ) );
			if ( signedMatch && signedMatch[1] ) {
				fetch( base + '/api/v1/ojs/verify-signed/?token=' + encodeURIComponent( signedMatch[1] ) )
					.then( function ( r ) { return r.json(); } )
					.then( function ( res ) {
						var d = res.content || res;
						if ( d.success && d.qr_code ) {
							showQRDetails( {
								name: d.qr_code.name || '',
								formatted_uuid: d.qr_code.formatted_uuid || d.qr_code.uuid || '',
								template_type: d.qr_code.template_type || d.qr_code.qr_type || '',
								scan_count: d.qr_code.scan_count || 0,
								is_active: d.qr_code.is_active !== false,
								creator: d.creator || null,
								anti_counterfeit: d.anti_counterfeit || null,
							}, data );
						} else {
							showBasicVerification( data );
						}
					} )
					.catch( function () { showBasicVerification( data ); } );
				return;
			}

			// Token-based verify-scan URL
			var tokenMatch = data.match( /[?&]t=([A-Za-z0-9_-]+)/ );
			if ( tokenMatch ) {
				var payload = { token: tokenMatch[1] };
				var sigM = data.match( /[?&]s=([A-Za-z0-9_-]+)/ );
				var verM = data.match( /[?&]v=([A-Za-z0-9]+)/ );
				if ( sigM ) payload.signature = sigM[1];
				if ( verM ) payload.version   = verM[1];

				fetch( base + '/api/v1/scan/verify/', {
					method: 'POST',
					headers: { 'Content-Type': 'application/json' },
					body: JSON.stringify( payload ),
				} )
				.then( function ( r ) { return r.json(); } )
				.then( function ( res ) {
					if ( res.success && res.is_verified ) {
						showQRDetails( {
							name: res.qr_code ? res.qr_code.name : '',
							formatted_uuid: res.qr_code ? res.qr_code.uuid : '',
							template_type: res.qr_code ? res.qr_code.template_type : '',
							scan_count: res.qr_code ? res.qr_code.scan_count : 0,
							is_active: res.qr_code ? res.qr_code.is_active : true,
							creator: res.creator || null,
							anti_counterfeit: res.anti_counterfeit || null,
						}, data );
					} else {
						showError( res.message || res.error || i18n.not_found );
					}
				} )
				.catch( function () { showBasicVerification( data ); } );
				return;
			}

			// Formatted UUID lookup
			var qrId = extractQRId( data );
			if ( qrId && /^[A-Z0-9]{4}-[A-Z0-9]{2}-[a-f0-9]+$/i.test( qrId ) ) {
				fetch( base + '/qr_codes/api/v1/qr/lookup/?formatted_uuid=' + encodeURIComponent( qrId ) )
					.then( function ( r ) { return r.json(); } )
					.then( function ( res ) {
						if ( res.success && res.data ) showQRDetails( res.data );
						else if ( data.includes( 'govalid.org' ) ) showBasicVerification( data );
						else showError( i18n.not_found || 'QR code not found' );
					} )
					.catch( function () {
						if ( data.includes( 'govalid.org' ) ) showBasicVerification( data );
						else showError( i18n.failed_search );
					} );
			} else if ( data.includes( 'govalid.org' ) ) {
				showBasicVerification( data );
			} else {
				showError( i18n.not_found || 'Unable to verify' );
			}
		}

		function extractQRId( data ) {
			if ( data.includes( 'govalid.org/' ) ) {
				var parts = data.split( '/' );
				var id = parts[ parts.length - 1 ] || parts[ parts.length - 2 ];
				if ( id && id.includes( '?' ) ) id = id.split( '?' )[0];
				return id;
			}
			if ( /^[A-Z0-9]{4}-[A-Z0-9]{2}-[a-zA-Z0-9]+$/i.test( data ) ) return data;
			return data;
		}

		/* ── UI helpers ─────────────────────────────────── */
		function showLoading() {
			resultsDiv.style.display = 'block';
			loadingDiv.style.display = 'flex';
			resultContent.innerHTML  = '';
		}
		function hideResults() {
			resultsDiv.style.display = 'none';
			loadingDiv.style.display = 'none';
			resultContent.innerHTML  = '';
		}
		function showError( msg ) {
			resultsDiv.style.display = 'block';
			loadingDiv.style.display = 'none';
			resultContent.innerHTML  = '<div class="govalid-sv-error"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"></circle><line x1="15" y1="9" x2="9" y2="15"></line><line x1="9" y1="9" x2="15" y2="15"></line></svg><span>' + esc( msg ) + '</span></div>';
		}

		function showBasicVerification( url ) {
			resultsDiv.style.display = 'block';
			loadingDiv.style.display = 'none';
			resultContent.innerHTML =
				'<div class="govalid-sv-result govalid-sv-result-success">' +
				'<div class="govalid-sv-result-header"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline></svg><span>' + esc( i18n.govalid_detected || 'GoValid QR Code Detected' ) + '</span></div>' +
				'<div class="govalid-sv-result-footer"><a href="' + esc( url ) + '" target="_blank" class="govalid-sv-btn-primary">' + esc( i18n.verify_on_govalid || 'Verify on GoValid' ) + '</a></div></div>';
		}

		function showQRDetails( data, verifyUrl ) {
			resultsDiv.style.display = 'block';
			loadingDiv.style.display = 'none';

			var ac = data.anti_counterfeit || {};
			var hasViolations = ac.has_violations || ac.has_violation || false;
			var acAction = ac.action || ac.violation_action || null;
			var isActive = data.is_active !== false;

			var statusClass, statusText, statusIcon;
			if ( hasViolations && acAction === 'block' ) {
				statusClass = 'danger';
				statusText  = i18n.counterfeit || 'Potentially Counterfeit';
				statusIcon  = '<circle cx="12" cy="12" r="10"></circle><line x1="15" y1="9" x2="9" y2="15"></line><line x1="9" y1="9" x2="15" y2="15"></line>';
			} else if ( hasViolations && acAction === 'warning' ) {
				statusClass = 'warning';
				statusText  = i18n.suspicious || 'Suspicious Activity';
				statusIcon  = '<path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path><line x1="12" y1="9" x2="12" y2="13"></line><line x1="12" y1="17" x2="12.01" y2="17"></line>';
			} else if ( ! isActive ) {
				statusClass = 'warning';
				statusText  = i18n.inactive || 'Inactive';
				statusIcon  = '<circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="12"></line><line x1="12" y1="16" x2="12.01" y2="16"></line>';
			} else {
				statusClass = 'success';
				statusText  = i18n.valid || 'Valid';
				statusIcon  = '<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline>';
			}

			var url = verifyUrl || data.verification_url || '';
			if ( ! url && data.formatted_uuid ) url = base + '/v/' + data.formatted_uuid;

			var creator       = data.creator || {};
			var generatedBy   = creator.full_name || creator.username || null;
			var institution   = creator.institution_name || null;
			var isVerified    = creator.is_verified || creator.staff_verified || false;
			var verifiedBadge = isVerified ? '<svg width="14" height="14" viewBox="0 0 24 24" fill="#1da1f2" style="margin-left:4px;vertical-align:middle;"><path d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>' : '';

			var html = '<div class="govalid-sv-result govalid-sv-result-' + statusClass + '">';
			html += '<div class="govalid-sv-result-header"><svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">' + statusIcon + '</svg><span>' + esc( statusText ) + ' ' + esc( i18n.govalid_qr || 'GoValid QR Code' ) + '</span></div>';

			// Anti-counterfeit warnings
			if ( hasViolations ) {
				var bgColor = acAction === 'block' ? '#fee2e2' : '#fef3c7';
				var bdColor = acAction === 'block' ? '#f87171' : '#fbbf24';
				var txColor = acAction === 'block' ? '#dc2626' : '#d97706';
				html += '<div style="background:' + bgColor + ';border:1px solid ' + bdColor + ';border-radius:6px;padding:10px;margin:10px 0;">';
				html += '<div style="font-weight:600;color:' + txColor + ';margin-bottom:6px;">' + esc( ac.violation_message || 'Suspicious activity detected' ) + '</div>';
				var violations = ac.violations || [];
				var vTypes     = ac.violation_types || [];
				if ( violations.length ) {
					violations.forEach( function ( v ) { html += '<div style="font-size:12px;color:#666;margin:4px 0;">&bull; ' + esc( v.title || v.type ) + '</div>'; } );
				} else if ( vTypes.length ) {
					vTypes.forEach( function ( t ) { html += '<div style="font-size:12px;color:#666;margin:4px 0;">&bull; ' + esc( t.replace( /_/g, ' ' ) ) + '</div>'; } );
				}
				html += '</div>';
			}

			html += '<div class="govalid-sv-result-body">';
			if ( data.name )           html += field( i18n.name || 'Name:', data.name );
			if ( data.formatted_uuid ) html += '<div class="govalid-sv-field"><label>' + esc( i18n.qr_id || 'QR ID:' ) + '</label><span class="govalid-sv-mono">' + esc( data.formatted_uuid ) + '</span></div>';
			if ( data.template_type )  html += field( i18n.type || 'Type:', data.template_type );
			if ( generatedBy )         html += '<div class="govalid-sv-field"><label>' + esc( i18n.generated_by || 'Generated by:' ) + '</label><span>' + esc( generatedBy ) + verifiedBadge + '</span></div>';
			if ( institution )         html += field( i18n.institution || 'Institution:', institution );
			if ( data.scan_count !== undefined ) html += field( i18n.scans || 'Scans:', String( data.scan_count ) );
			html += '</div>';
			if ( url ) html += '<div class="govalid-sv-result-footer"><a href="' + esc( url ) + '" target="_blank" class="govalid-sv-btn-primary">' + esc( i18n.view_details || 'View Full Details' ) + '</a></div>';
			html += '</div>';

			resultContent.innerHTML = html;
		}

		function field( label, value ) {
			return '<div class="govalid-sv-field"><label>' + esc( label ) + '</label><span>' + esc( value ) + '</span></div>';
		}
	}

	/* ── Helpers ─────────────────────────────────────────── */
	function esc( text ) {
		if ( ! text ) return '';
		var d = document.createElement( 'div' );
		d.textContent = text;
		return d.innerHTML;
	}

	function stopAllCameras() {
		document.querySelectorAll( '.govalid-sv-panel' ).forEach( function ( p ) {
			if ( typeof p._stopCamera === 'function' ) p._stopCamera();
		} );
	}

	/* ── Boot ────────────────────────────────────────────── */
	function boot() {
		initFloatingWidget();
		document.querySelectorAll( '.govalid-sv-panel' ).forEach( initPanel );
	}

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