/**
 * Copyfend — client-side deterrence engine.
 *
 * Deliberately lightweight and accessibility-aware: it never interferes with
 * form fields, contenteditable areas, or search engines (those are filtered
 * server-side before this script is even enqueued). This is *deterrence*, not
 * unbreakable security — see readme.txt.
 */
( function () {
	'use strict';

	var cfg = window.cshieldConfig || {};

	/**
	 * True for fields the user must be able to type/select in.
	 *
	 * @param {EventTarget} el Element.
	 * @return {boolean} Whether the element is editable.
	 */
	function isEditable( el ) {
		if ( ! el || ! el.tagName ) {
			return false;
		}
		var tag = el.tagName.toLowerCase();
		if ( 'input' === tag || 'textarea' === tag || 'select' === tag ) {
			return true;
		}
		if ( el.isContentEditable ) {
			return true;
		}
		return !! ( el.closest && el.closest( 'input, textarea, select, [contenteditable="true"]' ) );
	}

	var noticeEl = null;
	var noticeTimer = null;

	/**
	 * Show a brief, non-blocking toast.
	 */
	function showNotice() {
		if ( ! cfg.message ) {
			return;
		}
		if ( ! noticeEl ) {
			noticeEl = document.createElement( 'div' );
			noticeEl.setAttribute( 'role', 'status' );
			noticeEl.style.cssText = [
				'position:fixed', 'left:50%', 'bottom:24px', 'transform:translateX(-50%)',
				'background:rgba(20,20,20,.92)', 'color:#fff', 'padding:10px 16px',
				'border-radius:8px', 'font:14px/1.4 system-ui,-apple-system,sans-serif',
				'z-index:2147483647', 'box-shadow:0 6px 24px rgba(0,0,0,.25)',
				'pointer-events:none', 'opacity:0', 'transition:opacity .2s'
			].join( ';' );
			document.body.appendChild( noticeEl );
		}
		noticeEl.textContent = cfg.message;
		noticeEl.style.opacity = '1';
		window.clearTimeout( noticeTimer );
		noticeTimer = window.setTimeout( function () {
			noticeEl.style.opacity = '0';
		}, 1500 );
	}

	/**
	 * Generic blocker that respects editable fields.
	 *
	 * @param {Event} e Event.
	 */
	function blockEvent( e ) {
		if ( isEditable( e.target ) ) {
			return;
		}
		e.preventDefault();
		showNotice();
	}

	if ( cfg.rightClick ) {
		document.addEventListener( 'contextmenu', blockEvent );
	}

	if ( cfg.selection ) {
		var selStyle = document.createElement( 'style' );
		selStyle.textContent =
			'body.cs-noselect *:not(input):not(textarea):not(select):not([contenteditable="true"]){' +
			'-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}';
		document.head.appendChild( selStyle );
		document.body.classList.add( 'cs-noselect' );
		document.addEventListener( 'selectstart', function ( e ) {
			if ( ! isEditable( e.target ) ) {
				e.preventDefault();
			}
		} );
	}

	if ( cfg.imageDrag ) {
		document.addEventListener( 'dragstart', function ( e ) {
			if ( e.target && 'IMG' === e.target.tagName && ! isEditable( e.target ) ) {
				e.preventDefault();
			}
		} );
	}

	// One anonymous ping per page view when a copy got the attribution appended,
	// so the dashboard can show how many copies became backlinks. No visitor data.
	var pinged = false;
	function pingAttribution() {
		if ( pinged || ! cfg.pingUrl || ! navigator.sendBeacon ) {
			return;
		}
		pinged = true;
		var data = new FormData();
		data.append( 'action', 'cshield_copy_ping' );
		navigator.sendBeacon( cfg.pingUrl, data );
	}

	// Copy handler: either block, or allow and append attribution (the backlink play).
	document.addEventListener( 'copy', function ( e ) {
		if ( isEditable( e.target ) ) {
			return;
		}
		if ( cfg.copyCut ) {
			e.preventDefault();
			showNotice();
			return;
		}
		if ( cfg.attribution && e.clipboardData && window.getSelection ) {
			var selection = String( window.getSelection() );
			if ( selection ) {
				var note = ( cfg.attributionText || 'Source: {url}' ).replace( '{url}', window.location.href );
				e.clipboardData.setData( 'text/plain', selection + '\n\n' + note );
				e.preventDefault();
				pingAttribution();
			}
		}
	} );

	if ( cfg.copyCut ) {
		document.addEventListener( 'cut', blockEvent );
	}

	if ( cfg.shortcuts ) {
		document.addEventListener( 'keydown', function ( e ) {
			if ( isEditable( e.target ) ) {
				return;
			}
			var key = ( e.key || '' ).toLowerCase();
			var ctrl = e.ctrlKey || e.metaKey;
			if ( ctrl && [ 'c', 'x', 'a', 's', 'u' ].indexOf( key ) !== -1 ) {
				e.preventDefault();
				showNotice();
			} else if ( ctrl && 'p' === key && cfg.blockPrint ) {
				e.preventDefault();
				showNotice();
			}
		} );
	}

	if ( cfg.blockPrint ) {
		var printStyle = document.createElement( 'style' );
		printStyle.media = 'print';
		printStyle.textContent = 'body{display:none !important}';
		document.head.appendChild( printStyle );
	}
} )();
