/* global AIPB_SE */
/* WordPress's Site Editor is an SPA: opening a pattern (wp_block) or an FSE template
   (wp_template / wp_template_part) does NOT reload the page, so the PHP redirect is not enough.
   This guard watches the URL and, as soon as the editing of an entity OWNED BY AURA begins, it
   performs a full navigation to the Studio (which resolves/materialises the entity and opens it).
   Patterns and templates born in Gutenberg are not touched: they open in the Site Editor.

   WordPress has changed the Site Editor's URL scheme more than once: we handle both the query form
   (postType=wp_block&postId=123&canvas=edit) and the path form (p=/wp_block/123). */
( function () {
	'use strict';

	if ( typeof AIPB_SE === 'undefined' || ! AIPB_SE.studio ) {
		return;
	}

	var TYPES = {};
	( AIPB_SE.types || [] ).forEach( function ( t ) { TYPES[ t ] = 1; } );
	var typeAlt = Object.keys( TYPES ).join( '|' ); // wp_block|wp_template|wp_template_part|ai_section

	// Aura's entities: a numeric ID for the patterns, also "theme//slug" for the FSE templates.
	var OWNED = {};
	( AIPB_SE.owned || [] ).forEach( function ( k ) { OWNED[ String( k ) ] = 1; } );

	var redirecting = false;

	// Extracts { pt, id } from the current URL in both schemes, or null when it is not an edit.
	function target() {
		var p = new URLSearchParams( window.location.search );

		// Query form: postType + postId (+ canvas=edit while editing).
		var pt = p.get( 'postType' );
		var id = p.get( 'postId' );
		if ( pt && id && TYPES[ pt ] ) {
			return { pt: pt, id: id };
		}

		// Path form: p=/wp_block/123  or  p=/wp_template/theme//slug
		var path = p.get( 'p' ) || '';
		try { path = decodeURIComponent( path ); } catch ( e ) {}
		var m = path.match( new RegExp( '^/(' + typeAlt + ')/(.+)$' ) );
		if ( m ) {
			return { pt: m[ 1 ], id: m[ 2 ] };
		}
		return null;
	}

	function studioUrl( t ) {
		return AIPB_SE.studio
			+ '&se_pt=' + encodeURIComponent( t.pt )
			+ '&se_id=' + encodeURIComponent( t.id );
	}

	function check() {
		if ( redirecting ) { return; }
		var t = target();
		// target() already requires a specific id: the grid (with no id) does not match, so any
		// match here means "open THIS pattern/template".
		if ( ! t ) { hideOffer(); return; }

		// Already Aura's: divert straight away, without asking anything.
		if ( OWNED[ String( t.id ) ] ) {
			redirecting = true;
			hideOffer();
			window.location.href = studioUrl( t );
			return;
		}

		// Not claimed yet: do NOT divert. A template born in Gutenberg stays Gutenberg's until the
		// user says otherwise — taking it into Aura means materialising it in the database and
		// changing its editor, and that is not something to do behind their back. We offer them the
		// choice, and that is all.
		showOffer( t );
	}

	/* ---------------------- The offer: «Edit with Aura» ----------------------- */

	var offer = null;      // the box, created once
	var offerFor = '';     // which entity it is currently shown for
	var dismissed = {};    // entities the user said no to in this session

	function labels() {
		return AIPB_SE.i18n || {};
	}

	function buildOffer() {
		var L = labels();
		var box = document.createElement( 'div' );
		box.setAttribute( 'data-aipb-offer', '1' );
		box.style.cssText = 'position:fixed;right:20px;bottom:20px;z-index:2147483646;max-width:320px;'
			+ 'background:#fff;color:#1f2430;border:1px solid #e5e7eb;border-radius:14px;'
			+ 'box-shadow:0 1px 2px rgba(16,24,40,.04),0 12px 32px rgba(16,24,40,.14);'
			+ 'padding:14px 16px;font:13px/1.5 system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;';

		var title = document.createElement( 'div' );
		title.textContent = L.title || 'Edit with Aura?';
		title.style.cssText = 'font-weight:600;font-size:13.5px;margin-bottom:4px;';

		var desc = document.createElement( 'div' );
		desc.textContent = L.desc || '';
		desc.style.cssText = 'color:#6b7280;margin-bottom:12px;';

		var row = document.createElement( 'div' );
		row.style.cssText = 'display:flex;gap:8px;align-items:center;';

		var go = document.createElement( 'button' );
		go.type = 'button';
		go.textContent = L.open || 'Open in Aura';
		go.style.cssText = 'flex:1;border:0;border-radius:8px;background:#6d5efc;color:#fff;'
			+ 'font:inherit;font-weight:600;padding:8px 12px;cursor:pointer;';

		var no = document.createElement( 'button' );
		no.type = 'button';
		no.textContent = L.stay || 'Stay in Gutenberg';
		no.style.cssText = 'border:1px solid #e5e7eb;border-radius:8px;background:#fff;color:#6b7280;'
			+ 'font:inherit;padding:8px 12px;cursor:pointer;';

		go.addEventListener( 'click', function () {
			var t = target();
			if ( ! t ) { return; }
			redirecting = true;
			window.location.href = studioUrl( t );
		} );
		no.addEventListener( 'click', function () {
			if ( offerFor ) { dismissed[ offerFor ] = 1; }
			hideOffer();
		} );

		row.appendChild( go );
		row.appendChild( no );
		box.appendChild( title );
		box.appendChild( desc );
		box.appendChild( row );
		return box;
	}

	function showOffer( t ) {
		var key = t.pt + ':' + t.id;
		if ( dismissed[ key ] ) { hideOffer(); return; }
		if ( offerFor === key && offer && offer.isConnected ) { return; }

		if ( ! offer ) { offer = buildOffer(); }
		offerFor = key;
		if ( ! offer.isConnected ) { document.body.appendChild( offer ); }
	}

	function hideOffer() {
		offerFor = '';
		if ( offer && offer.isConnected ) { offer.remove(); }
	}

	// Intercept the SPA transitions (pushState/replaceState) and the back/forward buttons.
	[ 'pushState', 'replaceState' ].forEach( function ( m ) {
		var orig = window.history[ m ];
		window.history[ m ] = function () {
			var r = orig.apply( this, arguments );
			check();
			return r;
		};
	} );
	window.addEventListener( 'popstate', check );

	// A safety net for transitions that do not go through the methods above.
	window.setInterval( check, 350 );
	check();
} )();
