/**
 * Livada SEO — Admin JS
 * Vanilla JS, no jQuery dependency (WP admin jQuery available as fallback).
 */

/* global livadaSEO, wp */

( function () {
	'use strict';

	// Safety: bail if our localised object is missing.
	if ( typeof livadaSEO === 'undefined' ) {
		return;
	}

	const ajaxUrl = livadaSEO.ajaxUrl;
	const nonce   = livadaSEO.nonce;
	const str     = livadaSEO.strings;

	// ── Helpers ────────────────────────────────────────────────────────────────

	/**
	 * Generic AJAX POST helper. Returns a Promise resolving with parsed JSON.
	 *
	 * @param {string} action  wp_ajax action name.
	 * @param {Object} data    Additional POST data.
	 * @returns {Promise<Object>}
	 */
	function ajaxPost( action, data ) {
		const body = new URLSearchParams( Object.assign( { action, nonce }, data ) );
		return fetch( ajaxUrl, {
			method      : 'POST',
			credentials : 'same-origin',
			headers     : { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
			body        : body.toString(),
		} ).then( function ( r ) {
			if ( ! r.ok ) {
				throw new Error( 'HTTP ' + r.status );
			}
			return r.json();
		} );
	}

	// ── Repeater rows ──────────────────────────────────────────────────────────

	/**
	 * Initialise all repeaters on the page.
	 * Each repeater has:
	 *   - A container with id="livada-*-repeater" and class "livada-repeater"
	 *   - A hidden template row with class "livada-repeater-template"
	 *   - Remove buttons with class "livada-repeater-remove"
	 *   - An "Add" button outside the repeater with data-target="<repeater-id>"
	 */
	function initRepeaters() {
		// "Add row" buttons.
		document.querySelectorAll( '.livada-repeater-add' ).forEach( function ( btn ) {
			btn.addEventListener( 'click', function () {
				const targetId  = btn.getAttribute( 'data-target' );
				const container = document.getElementById( targetId );
				if ( ! container ) {
					return;
				}

				const template = container.querySelector( '.livada-repeater-template' );
				if ( ! template ) {
					return;
				}

				// Count existing non-template rows to determine the next index.
				const existing  = container.querySelectorAll( '.livada-repeater-row:not(.livada-repeater-template)' );
				const nextIndex = existing.length;

				const clone = template.cloneNode( true );
				clone.classList.remove( 'livada-repeater-template' );
				clone.style.display = '';
				clone.removeAttribute( 'aria-hidden' );

				// Replace __IDX__ placeholder in name attributes.
				clone.querySelectorAll( '[name]' ).forEach( function ( el ) {
					el.setAttribute( 'name', el.getAttribute( 'name' ).replace( /__IDX__/g, nextIndex ) );
				} );

				// Update any visible "Service N" counter text.
				const heading = clone.querySelector( '.livada-repeater-row__header strong' );
				if ( heading ) {
					heading.textContent = heading.textContent.replace( /\d+$/, '' ).trim() + ' ' + ( nextIndex + 1 );
				}

				// Wire up the remove button on the clone.
				const removeBtn = clone.querySelector( '.livada-repeater-remove' );
				if ( removeBtn ) {
					removeBtn.addEventListener( 'click', removeRow );
				}

				container.insertBefore( clone, template );
			} );
		} );

		// Remove buttons already present in the DOM (pre-populated rows).
		document.querySelectorAll( '.livada-repeater-remove' ).forEach( function ( btn ) {
			btn.addEventListener( 'click', removeRow );
		} );
	}

	function removeRow( e ) {
		const row = e.currentTarget.closest( '.livada-repeater-row' );
		if ( row ) {
			row.remove();
		}
	}

	// ── Media picker ───────────────────────────────────────────────────────────

	function initMediaPickers() {
		if ( typeof wp === 'undefined' || ! wp.media ) {
			return;
		}

		document.querySelectorAll( '.livada-media-upload' ).forEach( function ( btn ) {
			btn.addEventListener( 'click', function () {
				const targetId = btn.getAttribute( 'data-target' );
				openMediaFrame( targetId );
			} );
		} );

		document.querySelectorAll( '.livada-media-remove' ).forEach( function ( btn ) {
			btn.addEventListener( 'click', function () {
				const targetId = btn.getAttribute( 'data-target' );
				clearMedia( targetId );
			} );
		} );
	}

	function openMediaFrame( targetId ) {
		const frame = wp.media( {
			title    : str.chooseImage,
			button   : { text: str.useImage },
			multiple : false,
			library  : { type: 'image' },
		} );

		frame.on( 'select', function () {
			const attachment = frame.state().get( 'selection' ).first().toJSON();
			const input      = document.getElementById( targetId );
			const preview    = document.getElementById( targetId + '_preview' );
			const removeBtn  = document.querySelector( '.livada-media-remove[data-target="' + targetId + '"]' );

			if ( input ) {
				input.value = attachment.url;
			}
			if ( preview ) {
				preview.src          = attachment.url;
				preview.style.display = 'block';
			}
			if ( removeBtn ) {
				removeBtn.style.display = '';
			}
		} );

		frame.open();
	}

	function clearMedia( targetId ) {
		const input     = document.getElementById( targetId );
		const preview   = document.getElementById( targetId + '_preview' );
		const removeBtn = document.querySelector( '.livada-media-remove[data-target="' + targetId + '"]' );

		if ( input )     { input.value = ''; }
		if ( preview )   { preview.src = ''; preview.style.display = 'none'; }
		if ( removeBtn ) { removeBtn.style.display = 'none'; }
	}

	// ── Redirections: add ──────────────────────────────────────────────────────

	function initAddRedirectForm() {
		const form = document.getElementById( 'livada-add-redirect-form' );
		if ( ! form ) {
			return;
		}

		form.addEventListener( 'submit', function ( e ) {
			e.preventDefault();

			const msgEl  = document.getElementById( 'livada-add-redirect-message' );
			const source = form.querySelector( '[name="source_url"]' ).value.trim();
			const target = form.querySelector( '[name="target_url"]' ).value.trim();
			const type   = form.querySelector( '[name="type"]' ).value;

			showMessage( msgEl, '', '' );

			ajaxPost( 'livada_seo_add_redirect', { source_url: source, target_url: target, type: type } )
				.then( function ( res ) {
					if ( res.success ) {
						showMessage( msgEl, str.importDone || 'Redirect added.', 'success' );
						form.reset();
						// Reload the table after a short delay.
						setTimeout( function () { window.location.reload(); }, 800 );
					} else {
						showMessage( msgEl, ( res.data && res.data.message ) || str.importError, 'error' );
					}
				} )
				.catch( function () {
					showMessage( msgEl, str.importError, 'error' );
				} );
		} );
	}

	// ── Redirections: inline edit & delete ────────────────────────────────────

	function initRedirectTable() {
		const tbody = document.getElementById( 'livada-redirects-tbody' );
		if ( ! tbody ) {
			return;
		}

		tbody.addEventListener( 'click', function ( e ) {
			const btn = e.target.closest( 'button' );
			if ( ! btn ) {
				return;
			}

			const row = btn.closest( 'tr[data-id]' );
			if ( ! row ) {
				return;
			}

			const id = parseInt( row.getAttribute( 'data-id' ), 10 );

			if ( btn.classList.contains( 'livada-redirect-edit' ) ) {
				enterEditMode( row );
			} else if ( btn.classList.contains( 'livada-redirect-cancel' ) ) {
				exitEditMode( row );
			} else if ( btn.classList.contains( 'livada-redirect-save' ) ) {
				saveRedirectRow( row, id );
			} else if ( btn.classList.contains( 'livada-redirect-delete' ) ) {
				deleteRedirectRow( row, id );
			}
		} );
	}

	function enterEditMode( row ) {
		row.querySelectorAll( '.redirect-display-val' ).forEach( function ( el ) { el.style.display = 'none'; } );
		row.querySelectorAll( '.redirect-edit-val' ).forEach( function ( el ) { el.style.display = ''; } );

		toggleBtn( row, 'livada-redirect-edit',   true  );
		toggleBtn( row, 'livada-redirect-save',   false );
		toggleBtn( row, 'livada-redirect-cancel', false );
	}

	function exitEditMode( row ) {
		row.querySelectorAll( '.redirect-display-val' ).forEach( function ( el ) { el.style.display = ''; } );
		row.querySelectorAll( '.redirect-edit-val' ).forEach( function ( el ) { el.style.display = 'none'; } );

		toggleBtn( row, 'livada-redirect-edit',   false );
		toggleBtn( row, 'livada-redirect-save',   true  );
		toggleBtn( row, 'livada-redirect-cancel', true  );
	}

	function toggleBtn( row, cls, hide ) {
		const btn = row.querySelector( '.' + cls );
		if ( btn ) {
			btn.style.display = hide ? 'none' : '';
		}
	}

	function saveRedirectRow( row, id ) {
		const cells = {
			source_url : row.querySelector( '.redirect-source .redirect-edit-val' ),
			target_url : row.querySelector( '.redirect-target .redirect-edit-val' ),
			type       : row.querySelector( '.redirect-type .redirect-edit-val' ),
		};

		const data = {
			id         : id,
			source_url : cells.source_url ? cells.source_url.value : '',
			target_url : cells.target_url ? cells.target_url.value : '',
			type       : cells.type       ? cells.type.value       : 301,
		};

		ajaxPost( 'livada_seo_update_redirect', data )
			.then( function ( res ) {
				if ( res.success ) {
					// Update display values.
					if ( cells.source_url ) {
						row.querySelector( '.redirect-source .redirect-display-val' ).textContent = cells.source_url.value;
					}
					if ( cells.target_url ) {
						row.querySelector( '.redirect-target .redirect-display-val' ).textContent = cells.target_url.value;
					}
					if ( cells.type ) {
						row.querySelector( '.redirect-type .redirect-display-val' ).textContent = cells.type.value;
					}
					exitEditMode( row );
				} else {
					alert( ( res.data && res.data.message ) || str.importError );
				}
			} )
			.catch( function () {
				alert( str.importError );
			} );
	}

	function deleteRedirectRow( row, id ) {
		if ( ! window.confirm( str.confirmDelete ) ) {
			return;
		}

		ajaxPost( 'livada_seo_delete_redirect', { id: id } )
			.then( function ( res ) {
				if ( res.success ) {
					row.remove();
				} else {
					alert( ( res.data && res.data.message ) || str.importError );
				}
			} )
			.catch( function () {
				alert( str.importError );
			} );
	}

	// ── Batched importers (SEOPress, Yoast) ────────────────────────────────────

	/**
	 * Drives a batched import card. Card markup:
	 *   <div class="livada-tool-card" data-importer="..." data-ajax-action="...">
	 *     <button class="livada-import-btn">...</button>
	 *     <div class="livada-import-progress">
	 *       <div class="livada-progress-bar"></div>
	 *       <p class="livada-import-status"></p>
	 *       <details class="livada-import-warnings"><ul class="livada-import-warnings-list"></ul></details>
	 *     </div>
	 *   </div>
	 *
	 * Calls action_type=start, then action_type=batch repeatedly until done,
	 * then action_type=redirections for a final pass.
	 */
	function initBatchedImporters() {
		document.querySelectorAll( '.livada-tool-card[data-importer]' ).forEach( function ( card ) {
			const btn          = card.querySelector( '.livada-import-btn' );
			const progressWrap = card.querySelector( '.livada-import-progress' );
			const bar          = card.querySelector( '.livada-progress-bar' );
			const statusEl     = card.querySelector( '.livada-import-status' );
			const warnDetails  = card.querySelector( '.livada-import-warnings' );
			const warnList     = card.querySelector( '.livada-import-warnings-list' );
			const ajaxAction   = card.getAttribute( 'data-ajax-action' );

			if ( ! btn || ! ajaxAction ) {
				return;
			}

			btn.addEventListener( 'click', function () {
				btn.disabled              = true;
				progressWrap.style.display = 'block';
				bar.style.width            = '0%';
				statusEl.textContent       = str.importing;
				if ( warnDetails ) {
					warnDetails.style.display = 'none';
					warnList.innerHTML        = '';
				}

				const allWarnings = [];

				function appendWarnings( warnings ) {
					if ( ! Array.isArray( warnings ) || warnings.length === 0 ) {
						return;
					}
					warnings.forEach( function ( w ) { allWarnings.push( w ); } );
				}

				function showWarnings() {
					if ( ! warnDetails || allWarnings.length === 0 ) {
						return;
					}
					warnList.innerHTML = '';
					allWarnings.forEach( function ( w ) {
						const li = document.createElement( 'li' );
						li.textContent = w;
						warnList.appendChild( li );
					} );
					warnDetails.style.display = '';
				}

				// Phase 1: start.
				ajaxPost( ajaxAction, { action_type: 'start' } )
					.then( function ( res ) {
						if ( ! res.success ) {
							throw new Error( ( res.data && res.data.message ) || 'start failed' );
						}
						const total = ( res.data && res.data.total ) || 0;
						statusEl.textContent = str.importing + ' 0 / ' + total;

						// Phase 2: loop batches until done.
						return runBatches( ajaxAction, total, bar, statusEl, appendWarnings );
					} )
					// Phase 3: redirections (best-effort; ignore failures).
					.then( function () {
						return ajaxPost( ajaxAction, { action_type: 'redirections' } )
							.then( function ( res ) {
								if ( res.success && res.data ) {
									appendWarnings( res.data.warnings );
									if ( typeof res.data.imported === 'number' ) {
										statusEl.textContent +=
											' — ' +
											res.data.imported +
											' redirects imported, ' +
											( res.data.skipped || 0 ) +
											' skipped';
									}
								}
							} )
							.catch( function () { /* swallow — redirections are optional */ } );
					} )
					.then( function () {
						bar.style.width      = '100%';
						statusEl.textContent = str.importDone +
							( allWarnings.length ? ' (' + allWarnings.length + ' warnings)' : '' );
						showWarnings();
					} )
					.catch( function ( err ) {
						bar.style.width      = '0%';
						statusEl.textContent = ( err && err.message ) || str.importError;
						btn.disabled         = false;
						showWarnings();
					} );
			} );
		} );
	}

	/**
	 * Runs the batch loop until the server reports done = true.
	 */
	function runBatches( ajaxAction, total, bar, statusEl, appendWarnings ) {
		return new Promise( function ( resolve, reject ) {
			function step() {
				ajaxPost( ajaxAction, { action_type: 'batch' } )
					.then( function ( res ) {
						if ( ! res.success ) {
							reject( new Error( ( res.data && res.data.message ) || 'batch failed' ) );
							return;
						}

						appendWarnings( res.data && res.data.warnings );

						const processed = ( res.data && res.data.processed ) || 0;
						const knownTotal = ( res.data && res.data.total ) || total;
						const pct        = knownTotal > 0
							? Math.min( 95, Math.round( ( processed / knownTotal ) * 95 ) )
							: 50;

						bar.style.width      = pct + '%';
						statusEl.textContent = str.importing + ' ' + processed + ' / ' + knownTotal;

						if ( res.data && res.data.done ) {
							resolve();
						} else {
							// Yield to the browser so the progress bar paints.
							setTimeout( step, 0 );
						}
					} )
					.catch( reject );
			}

			step();
		} );
	}

	// ── IndexNow regenerate ────────────────────────────────────────────────────

	function initRegenerateIndexNow() {
		const btn      = document.getElementById( 'livada-regenerate-indexnow' );
		const statusEl = document.getElementById( 'livada-regenerate-indexnow-status' );
		const keyEl    = document.getElementById( 'livada-indexnow-key' );

		if ( ! btn ) {
			return;
		}

		btn.addEventListener( 'click', function () {
			btn.disabled         = true;
			statusEl.textContent = str.regenerating;

			ajaxPost( 'livada_seo_regenerate_indexnow', {} )
				.then( function ( res ) {
					btn.disabled = false;
					if ( res.success && res.data && res.data.key ) {
						if ( keyEl ) {
							keyEl.textContent = res.data.key;
						}
						statusEl.textContent = '';
						// Reload to refresh the key file URL link.
						window.location.reload();
					} else {
						statusEl.textContent = ( res.data && res.data.message ) || str.importError;
					}
				} )
				.catch( function () {
					btn.disabled         = false;
					statusEl.textContent = str.importError;
				} );
		} );
	}

	// ── Reset settings ─────────────────────────────────────────────────────────

	function initResetSettings() {
		const btn      = document.getElementById( 'livada-reset-settings' );
		const statusEl = document.getElementById( 'livada-reset-status' );

		if ( ! btn ) {
			return;
		}

		btn.addEventListener( 'click', function () {
			if ( ! window.confirm( str.confirmReset ) ) {
				return;
			}

			btn.disabled         = true;
			statusEl.textContent = '…';

			ajaxPost( 'livada_seo_reset_settings', {} )
				.then( function ( res ) {
					btn.disabled = false;
					if ( res.success ) {
						statusEl.textContent = ( res.data && res.data.message ) || 'Done.';
						setTimeout( function () { window.location.reload(); }, 1000 );
					} else {
						statusEl.textContent = ( res.data && res.data.message ) || str.importError;
					}
				} )
				.catch( function () {
					btn.disabled         = false;
					statusEl.textContent = str.importError;
				} );
		} );
	}

	// ── Utility: show inline message ───────────────────────────────────────────

	function showMessage( el, text, type ) {
		if ( ! el ) {
			return;
		}
		el.textContent     = text;
		el.className       = 'livada-inline-message';
		el.style.display   = text ? '' : 'none';
		if ( type === 'success' ) {
			el.classList.add( 'is-success' );
		} else if ( type === 'error' ) {
			el.classList.add( 'is-error' );
		}
	}

	// ── Boot ───────────────────────────────────────────────────────────────────

	// ── Redirect bulk delete + CSV import ──────────────────────────────────────

	function initRedirectBulkOps() {
		const checkAll = document.getElementById( 'livada-redirects-check-all' );
		const bulkBtn  = document.getElementById( 'livada-bulk-delete-btn' );
		const statusEl = document.getElementById( 'livada-bulk-status' );
		const tbody    = document.getElementById( 'livada-redirects-tbody' );

		if ( ! bulkBtn || ! tbody ) {
			return;
		}

		bulkBtn.setAttribute( 'data-base-label', bulkBtn.textContent.trim() );

		function updateBulkBtn() {
			const checked = tbody.querySelectorAll( '.livada-redirect-cb:checked' ).length;
			bulkBtn.disabled = checked === 0;
			bulkBtn.textContent = checked > 0
				? bulkBtn.getAttribute( 'data-base-label' ) + ' (' + checked + ')'
				: bulkBtn.getAttribute( 'data-base-label' );
		}

		if ( checkAll ) {
			checkAll.addEventListener( 'change', function () {
				tbody.querySelectorAll( '.livada-redirect-cb' ).forEach( function ( cb ) {
					cb.checked = checkAll.checked;
				} );
				updateBulkBtn();
			} );
		}

		tbody.addEventListener( 'change', function ( e ) {
			if ( e.target && e.target.classList && e.target.classList.contains( 'livada-redirect-cb' ) ) {
				updateBulkBtn();
			}
		} );

		bulkBtn.addEventListener( 'click', function () {
			const ids = Array.prototype.slice
				.call( tbody.querySelectorAll( '.livada-redirect-cb:checked' ) )
				.map( function ( cb ) { return parseInt( cb.value, 10 ); } )
				.filter( function ( id ) { return id > 0; } );

			if ( ! ids.length ) { return; }
			if ( ! window.confirm( str.confirmDelete + ' (' + ids.length + ')' ) ) { return; }

			bulkBtn.disabled    = true;
			statusEl.textContent = '…';

			// Build a body with repeated `ids[]=N` keys so PHP receives an array.
			const body = new URLSearchParams();
			body.append( 'action', 'livada_seo_bulk_delete_redirects' );
			body.append( 'nonce',  nonce );
			ids.forEach( function ( id ) { body.append( 'ids[]', id ); } );

			fetch( ajaxUrl, {
				method:      'POST',
				credentials: 'same-origin',
				headers:     { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
				body:        body.toString(),
			} )
				.then( function ( r ) { return r.json(); } )
				.then( function ( res ) {
					if ( res.success ) {
						ids.forEach( function ( id ) {
							const row = tbody.querySelector( 'tr[data-id="' + id + '"]' );
							if ( row ) { row.remove(); }
						} );
						statusEl.textContent = ( res.data && res.data.deleted )
							? res.data.deleted + ' deleted'
							: '';
						updateBulkBtn();
					} else {
						statusEl.textContent = ( res.data && res.data.message ) || str.importError;
						bulkBtn.disabled     = false;
					}
				} )
				.catch( function () {
					statusEl.textContent = str.importError;
					bulkBtn.disabled     = false;
				} );
		} );
	}

	function initCSVImport() {
		const form     = document.getElementById( 'livada-csv-import-form' );
		const statusEl = document.getElementById( 'livada-csv-import-status' );

		if ( ! form ) { return; }

		form.addEventListener( 'submit', function ( e ) {
			e.preventDefault();

			const fd = new FormData( form );
			fd.append( 'action', 'livada_seo_import_redirects_csv' );
			fd.append( 'nonce', nonce );

			statusEl.textContent = str.importing;

			fetch( ajaxUrl, {
				method:      'POST',
				credentials: 'same-origin',
				body:        fd,
			} )
				.then( function ( r ) { return r.json(); } )
				.then( function ( res ) {
					if ( res.success ) {
						statusEl.textContent =
							( res.data.imported || 0 ) + ' imported, ' +
							( res.data.skipped || 0 ) + ' skipped';
						setTimeout( function () { window.location.reload(); }, 1500 );
					} else {
						statusEl.textContent = ( res.data && res.data.message ) || str.importError;
					}
				} )
				.catch( function () {
					statusEl.textContent = str.importError;
				} );
		} );
	}

	document.addEventListener( 'DOMContentLoaded', function () {
		initRepeaters();
		initMediaPickers();
		initAddRedirectForm();
		initRedirectTable();
		initRedirectBulkOps();
		initCSVImport();
		initBatchedImporters();
		initRegenerateIndexNow();
		initResetSettings();
	} );

} )();
