/**
 * Dynamic OG Image Generator — Settings page JS.
 */
( function ( $ ) {
	'use strict';

	const s = doigAdmin.strings;

	// --- Proxy health check + usage fetch (single AJAX, fires on page load) ---
	//
	// The same admin-ajax endpoint returns both the connectivity result and
	// (if connected) the calling licence's usage figures. The reachable/
	// unreachable label updates #doig-proxy-status; the usage block updates
	// #doig-usage when present.
	( function () {
		const $status = $( '#doig-proxy-status' );
		const $usage  = $( '#doig-usage' );
		if ( ! $status.length && ! $usage.length ) return;

		$.post( doigAdmin.ajaxUrl, {
			action: 'doig_check_proxy_health',
			nonce:  doigAdmin.nonce,
		} )
		.done( function ( res ) {
			if ( res.success ) {
				$status
					.removeClass( 'doig-proxy-status--checking doig-proxy-status--err' )
					.addClass( 'doig-proxy-status--ok' )
					.text( '✓ ' + s.proxyReachable );

				if ( $usage.length ) {
					renderUsage( res.data && res.data.usage, res.data && res.data.usage_error );
				}
			} else {
				// res.data.message is intentionally empty server-side -
				// technical detail is in the plugin log. If a future
				// caller does include a message, we still display it
				// after a dash, but the default path is just the
				// friendly "Screenshot server unreachable" label.
				const msg = ( res.data && res.data.message ) ? res.data.message : '';
				$status
					.removeClass( 'doig-proxy-status--checking doig-proxy-status--ok' )
					.addClass( 'doig-proxy-status--err' )
					.text( '✗ ' + s.proxyUnreachable + ( msg ? ' — ' + msg : '' ) );

				if ( $usage.length ) {
					// Pass an empty error so the usage block falls
					// through to its own friendly fallback rather than
					// surfacing the proxy-health label here.
					renderUsage( null, '' );
				}
			}
		} )
		.fail( function () {
			$status
				.removeClass( 'doig-proxy-status--checking doig-proxy-status--ok' )
				.addClass( 'doig-proxy-status--err' )
				.text( '✗ ' + s.proxyUnreachable );

			if ( $usage.length ) {
				// Empty error -> usage block shows its own friendly fallback.
				renderUsage( null, '' );
			}
		} );

		/**
		 * Render the usage block inside #doig-usage.
		 *
		 * usage: object or null (per /v1/usage response shape).
		 * error: string or null (display when usage is null).
		 */
		function renderUsage( usage, error ) {
			$usage.removeClass( 'doig-usage--loading' );

			if ( ! usage ) {
				$usage.html(
					'<p class="description">' + escapeHtml( error || s.usageUnavailable ) + '</p>'
				);
				return;
			}

			// Headline quota line - the first thing the eye reads. Free plans
			// have no monthly allowance so we frame around startup capacity;
			// paid plans frame around monthly capacity.
			const monthlyCap   = usage.monthly_quota | 0;
			const monthlyUsed  = usage.monthly_used  | 0;
			const startupCap   = usage.startup_per_site_quota | 0;
			const startupUsed  = usage.startup_used  | 0;
			const planName     = doigAdmin.planName || 'Free';
			const headline     = monthlyCap > 0
				? sprintf( s.usageHeadlinePaid, planName, Math.max( 0, monthlyCap - monthlyUsed ), monthlyCap )
				: sprintf( s.usageHeadlineFree, Math.max( 0, startupCap - startupUsed ) );
			let headlineHtml = '<p class="doig-usage__headline" style="font-size:14px;font-weight:600;margin:0 0 12px;">' + escapeHtml( headline );
			if ( ! doigAdmin.isPaying && doigAdmin.upgradeUrl ) {
				headlineHtml += ' <a href="' + escapeHtml( doigAdmin.upgradeUrl ) + '" target="_blank" rel="noopener noreferrer" style="font-weight:500;">' + escapeHtml( s.usageTryPremiumLink ) + '</a>';
			}
			headlineHtml += '</p>';

			const rows = [];

			// Startup row - always shown (every plan has a startup allowance).
			rows.push(
				'<tr><th scope="row" style="padding:4px 12px 4px 0;text-align:left;width:1%;white-space:nowrap;font-weight:600;">' +
					escapeHtml( s.usageStartup ) +
					'</th><td style="padding:4px 0;">' +
					escapeHtml( String( usage.startup_used ) ) +
					' ' + escapeHtml( s.usageOf ) + ' ' +
					escapeHtml( String( usage.startup_per_site_quota ) ) +
					'</td></tr>'
			);

			// Monthly row - only when the plan includes a monthly allowance.
			if ( ( usage.monthly_quota | 0 ) > 0 ) {
				rows.push(
					'<tr><th scope="row" style="padding:4px 12px 4px 0;text-align:left;width:1%;white-space:nowrap;font-weight:600;">' +
						escapeHtml( s.usageMonthly ) +
						'</th><td style="padding:4px 0;">' +
						escapeHtml( String( usage.monthly_used ) ) +
						' ' + escapeHtml( s.usageOf ) + ' ' +
						escapeHtml( String( usage.monthly_quota ) ) +
						'</td></tr>'
				);

				// Quota window reset date. quota_period_end is the last day
				// INCLUDED in the current window; the quota rolls over the
				// day after, so add one day for the user-facing label.
				if ( usage.quota_period_end ) {
					rows.push(
						'<tr><th scope="row" style="padding:4px 12px 4px 0;text-align:left;width:1%;white-space:nowrap;font-weight:600;">' +
							escapeHtml( s.usageResetsOn ) +
							'</th><td style="padding:4px 0;">' +
							escapeHtml( formatDate( addOneDay( usage.quota_period_end ) ) ) +
							'</td></tr>'
					);
				}

				// Subscription renewal date - only for non-lifetime paid
				// plans (lifetime returns null for subscription_period_end).
				// Shown separately so customers can see when their billing
				// cycle renews, independent of the monthly quota reset.
				if ( usage.subscription_period_end ) {
					rows.push(
						'<tr><th scope="row" style="padding:4px 12px 4px 0;text-align:left;width:1%;white-space:nowrap;font-weight:600;">' +
							escapeHtml( s.usageRenewsOn ) +
							'</th><td style="padding:4px 0;">' +
							escapeHtml( formatDate( usage.subscription_period_end ) ) +
							'</td></tr>'
					);
				}
			}

			$usage.html(
				headlineHtml +
				'<table style="border-collapse:collapse;">' + rows.join( '' ) + '</table>'
			);
		}

		/**
		 * Minimal sprintf for %s / %d substitution against the headline
		 * templates. No locale-aware formatting needed - the templates are
		 * plain "%1$s ... %2$d ..." patterns produced by PHP's __().
		 */
		function sprintf( template ) {
			const args = Array.prototype.slice.call( arguments, 1 );
			return String( template ).replace( /%(\d+)\$[sd]/g, function( _, idx ) {
				return String( args[ parseInt( idx, 10 ) - 1 ] );
			} );
		}

		function escapeHtml( str ) {
			return String( str )
				.replace( /&/g, '&amp;' )
				.replace( /</g, '&lt;' )
				.replace( />/g, '&gt;' )
				.replace( /"/g, '&quot;' )
				.replace( /'/g, '&#39;' );
		}

		/**
		 * Add one day to a YYYY-MM-DD string, returning the same format.
		 * Used to turn "last day of the quota window" into "reset date".
		 * Falls back to the raw string if parsing fails.
		 */
		function addOneDay( iso ) {
			const d = new Date( iso + 'T00:00:00Z' );
			if ( isNaN( d.getTime() ) ) return iso;
			d.setUTCDate( d.getUTCDate() + 1 );
			return d.toISOString().slice( 0, 10 );
		}

		/**
		 * Format an ISO YYYY-MM-DD date in the locale-aware long form
		 * (e.g. "1 May 2026"). Falls back to the raw string if Date
		 * parsing fails.
		 */
		function formatDate( iso ) {
			const d = new Date( iso + 'T00:00:00Z' );
			if ( isNaN( d.getTime() ) ) return iso;
			try {
				return d.toLocaleDateString( undefined, {
					day:   'numeric',
					month: 'long',
					year:  'numeric',
				} );
			} catch ( e ) {
				return iso;
			}
		}
	} )();

	// --- Clear Cache ---
	$( '#doig-clear-cache' ).on( 'click', function () {
		const $btn    = $( this );
		const $result = $( '#doig-cache-result' );

		if ( ! confirm( 'Clear all cached screenshots? Existing og:images will fall back until new screenshots are generated.' ) ) {
			return;
		}

		$btn.prop( 'disabled', true );
		$result.removeClass( 'doig-ok doig-err' ).text( s.clearing );

		$.post( doigAdmin.ajaxUrl, {
			action: 'doig_clear_cache',
			nonce:  doigAdmin.nonce,
		} )
		.done( function ( res ) {
			if ( res.success ) {
				$result.addClass( 'doig-ok' ).text( res.data.message );
				$( '#doig-cache-count' ).text( '0' );
				$( '#doig-cache-size' ).text( '0 B' );
			} else {
				$result.addClass( 'doig-err' ).text( res.data.message );
			}
		} )
		.always( function () {
			$btn.prop( 'disabled', false );
		} );
	} );

	// --- Regenerate All ---
	$( '#doig-regenerate-all' ).on( 'click', function () {
		const $btn    = $( this );
		const $result = $( '#doig-cache-result' );

		if ( ! confirm( 'Queue new screenshots for all enabled pages and posts? This will use your monthly screenshot quota.' ) ) {
			return;
		}

		$btn.prop( 'disabled', true );
		$result.removeClass( 'doig-ok doig-err' ).text( s.regenerating );

		$.post( doigAdmin.ajaxUrl, {
			action: 'doig_regenerate_all',
			nonce:  doigAdmin.nonce,
		} )
		.done( function ( res ) {
			if ( res.success ) {
				$result.addClass( 'doig-ok' ).text( res.data.message );
			} else {
				$result.addClass( 'doig-err' ).text( res.data.message );
			}
		} )
		.always( function () {
			$btn.prop( 'disabled', false );
		} );
	} );

	// --- Media Library picker for fallback image ---
	var mediaFrame;

	$( '#doig-select-image' ).on( 'click', function ( e ) {
		e.preventDefault();

		if ( mediaFrame ) {
			mediaFrame.open();
			return;
		}

		mediaFrame = wp.media( {
			title:    s.selectImage,
			button:   { text: s.useImage },
			multiple: false,
			library:  { type: 'image' },
		} );

		mediaFrame.on( 'select', function () {
			var attachment = mediaFrame.state().get( 'selection' ).first().toJSON();
			$( '#doig_fallback_image_id' ).val( attachment.id );
			var previewUrl = attachment.sizes && attachment.sizes.thumbnail
				? attachment.sizes.thumbnail.url
				: attachment.url;
			$( '#doig-fallback-preview' ).attr( 'src', previewUrl ).show();
			$( '#doig-remove-image' ).show();
		} );

		mediaFrame.open();
	} );

	$( document ).on( 'click', '#doig-remove-image', function ( e ) {
		e.preventDefault();
		$( '#doig_fallback_image_id' ).val( 0 );
		$( '#doig-fallback-preview' ).attr( 'src', '' ).hide();
		$( this ).hide();
	} );

	// --- Show/hide custom image picker based on fallback type ---
	function toggleFallbackImage() {
		var selected = $( '.doig-fallback-radio:checked' ).val();
		if ( selected === 'media' ) {
			$( '#doig-fallback-image-wrap' ).closest( 'tr' ).show();
		} else {
			$( '#doig-fallback-image-wrap' ).closest( 'tr' ).hide();
		}
	}

	$( '.doig-fallback-radio' ).on( 'change', toggleFallbackImage );
	toggleFallbackImage(); // run on load

	// --- Media Library subordinate field dependency ---
	// When "Save to Media Library" is unchecked, grey out and block interaction with
	// the subordinate fields (Delete previous capture, Set as Featured Image).
	// We use opacity + pointer-events rather than disabled so the checkbox values are
	// still submitted with the form — preserving the user's choices if they re-enable.
	function toggleMediaLibrarySubordinates() {
		var $sub = $( '#doig-ml-subordinate' );
		if ( ! $sub.length ) return;

		if ( $( '#doig-save-to-media-library' ).is( ':checked' ) ) {
			$sub.css( { opacity: '', 'pointer-events': '' } );
		} else {
			$sub.css( { opacity: '0.38', 'pointer-events': 'none' } );
		}
	}

	$( '#doig-save-to-media-library' ).on( 'change', toggleMediaLibrarySubordinates );
	toggleMediaLibrarySubordinates(); // apply correct state on page load

	// Logs tab controls (save level / clear / download) are plain admin-post
	// forms rendered by the shared-logging component (DOIG_Log_UI) - no JS.

	// --- Recent activity: full-size image lightbox (2.5.2) ---
	//
	// Click (not hover) so it works on touch devices too. Ported from SSAA's
	// preview lightbox; DOIG needs no crop-frame overlay, just the image.
	// The lightbox markup only exists on the Dashboard, so the delegated
	// handlers below are inert on the Settings page.
	var $doigLightbox    = $( '#doig-img-lightbox' );
	var $doigLightboxImg = $( '#doig-img-lightbox-img' );

	function doigCloseLightbox() {
		$doigLightbox.attr( 'hidden', 'hidden' ).removeClass( 'doig-open' );
		$doigLightboxImg.attr( 'src', '' );
		$( document.body ).removeClass( 'doig-modal-open' );
	}

	$( document ).on( 'click', '.doig-zoomable', function ( e ) {
		e.preventDefault();
		var src = $( this ).data( 'full' ) || $( this ).attr( 'src' );
		if ( ! src ) {
			return;
		}
		$doigLightboxImg.attr( 'src', src );
		$doigLightbox.removeAttr( 'hidden' ).addClass( 'doig-open' );
		$( document.body ).addClass( 'doig-modal-open' );
	} );

	$( document ).on( 'click', '.doig-img-lightbox-close', function () {
		doigCloseLightbox();
	} );

	// Backdrop click only: clicking the image itself must not close it.
	$( document ).on( 'click', '.doig-img-lightbox', function ( e ) {
		if ( e.target === this ) {
			doigCloseLightbox();
		}
	} );

	$( document ).on( 'keydown', function ( e ) {
		if ( 'Escape' === e.key && $doigLightbox.hasClass( 'doig-open' ) ) {
			doigCloseLightbox();
		}
	} );

	// -------------------------------------------------------------------------
	// Site-wide Pages rows (2.7.0 M3): show the custom-image picker only
	// while the row's Source is "Custom image", and drive the picker with
	// the standard wp.media frame. wp_enqueue_media() is already called on
	// plugin screens by DOIG_Admin::enqueue_assets().
	// -------------------------------------------------------------------------

	$( document ).on( 'change', '.doig-surface-mode', function () {
		var $picker = $( this ).closest( '.doig-surface-row' ).find( '.doig-surface-custom' );
		if ( 'custom' === $( this ).val() ) {
			$picker.css( 'display', 'inline-flex' );
		} else {
			$picker.hide();
		}
	} );

	$( document ).on( 'click', '.doig-surface-custom-choose', function ( e ) {
		e.preventDefault();

		if ( ! window.wp || ! wp.media ) {
			return;
		}

		var l10n    = ( window.doigAdmin && doigAdmin.strings ) || {};
		var $row    = $( this ).closest( '.doig-surface-row' );
		var $button = $( this );
		var frame   = wp.media( {
			title:    l10n.surfaceChooseTitle || 'Choose an image',
			library:  { type: 'image' },
			multiple: false,
			button:   { text: l10n.surfaceChooseButton || 'Use this image' }
		} );

		frame.on( 'select', function () {
			var attachment = frame.state().get( 'selection' ).first().toJSON();
			var thumb      = ( attachment.sizes && attachment.sizes.thumbnail )
				? attachment.sizes.thumbnail.url
				: attachment.url;

			$row.find( '.doig-surface-custom-id' ).val( attachment.id );
			$row.find( '.doig-surface-custom-thumb' ).attr( 'src', thumb ).show();
			$button.text( l10n.surfaceChangeButton || 'Change image' );
		} );

		frame.open();
	} );

} )( jQuery );
