/**
 * Row action handlers for Cart Recovery table
 *
 * @package EDD\Pro\CartRecovery\Admin
 */

import { ajaxPost } from './ajax.js';
import { showNotice } from './notices.js';

/**
 * Handles mark recovered and delete cart actions.
 *
 * @param {Event}  e      - The click event.
 * @param {Object} config - Configuration object with messages, nonce, ajaxurl.
 */
export function handleRowAction( e, config ) {
	const target = e.target;

	if ( ! target.classList.contains( 'edd-acr-mark-recovered' ) &&
		! target.classList.contains( 'edd-acr-delete-cart' ) ) {
		return;
	}

	e.preventDefault();

	const cartId = target.dataset.cartId;
	if ( ! cartId || target.disabled ) {
		return;
	}

	const action = determineAction( target );
	target.disabled = true;

	performRowAction( target, cartId, action, config );
}

/**
 * Determines the action based on button class.
 *
 * @param {HTMLElement} target - The clicked button.
 * @return {string} The action name.
 */
function determineAction( target ) {
	if ( target.classList.contains( 'edd-acr-mark-recovered' ) ) {
		return 'mark_recovered';
	}
	return 'delete_cart';
}

/**
 * Performs the row action via AJAX.
 *
 * @param {HTMLElement} target - The clicked button.
 * @param {string}      cartId - The cart ID.
 * @param {string}      action - The action to perform.
 * @param {Object}      config - Configuration object.
 */
function performRowAction( target, cartId, action, config ) {
	const { messages, nonce, ajaxurl } = config;

	ajaxPost( ajaxurl, {
		action: 'edd_acr_' + action,
		cart_id: cartId,
		nonce: nonce,
	} )
		.then( function ( res ) {
			if ( res?.success ) {
				handleSuccess( target, action, messages );
			} else {
				handleError( target, res, messages );
			}
		} )
		.catch( function ( error ) {
			console.error( 'ACR admin action failed:', error );
			showNotice( messages.networkError, messages );
		} )
		.finally( function () {
			target.disabled = false;
		} );
}

/**
 * Handles successful row action.
 *
 * @param {HTMLElement} target   - The clicked button.
 * @param {string}      action   - The action performed.
 * @param {Object}      messages - Messages configuration.
 */
function handleSuccess( target, action, messages ) {
	const row = target.closest( 'tr' );

	if ( action === 'delete_cart' ) {
		handleDeleteSuccess( row, messages );
	} else if ( action === 'mark_recovered' ) {
		handleMarkRecoveredSuccess( row, messages );
	}
}

/**
 * Handles successful delete action.
 *
 * @param {HTMLElement} row      - The table row.
 * @param {Object}      messages - Messages configuration.
 */
function handleDeleteSuccess( row, messages ) {
	row.style.transition = 'opacity 0.4s';
	row.style.opacity = '0';

	setTimeout( function () {
		if ( row.parentNode ) {
			row.remove();
		}
		updateRowCount( messages );
	}, 400 );
}

/**
 * Updates the displayed row count after deletion.
 *
 * @param {Object} messages - Messages configuration.
 */
function updateRowCount( messages ) {
	const countDisplay = document.querySelector( '.displaying-num' );
	if ( ! countDisplay ) {
		return;
	}

	const match = /\d+/.exec( countDisplay.textContent );
	if ( match ) {
		const currentCount = Number.parseInt( match[ 0 ], 10 );
		countDisplay.textContent = ( currentCount - 1 ) + ' ' + messages.items;
	}
}

/**
 * Handles successful mark recovered action.
 *
 * @param {HTMLElement} row      - The table row.
 * @param {Object}      messages - Messages configuration.
 */
function handleMarkRecoveredSuccess( row, messages ) {
	// Add success animation
	row.classList.add( 'edd-acr-row-success' );
	setTimeout( function () {
		row.classList.remove( 'edd-acr-row-success' );
	}, 1500 );

	updateStatusBadge( row, messages );
	cleanupRowActions( row );
}

/**
 * Updates the status badge to "Recovered".
 *
 * @param {HTMLElement} row      - The table row.
 * @param {Object}      messages - Messages configuration.
 */
function updateStatusBadge( row, messages ) {
	const statusCell = row.querySelector( 'td.column-status' );
	if ( ! statusCell ) {
		return;
	}

	const statusBadge = statusCell.querySelector( '.edd-status-badge' );
	if ( ! statusBadge ) {
		return;
	}

	// Update text content
	const statusText = statusBadge.querySelector( '.edd-status-badge__text' );
	if ( statusText ) {
		statusText.textContent = messages.recovered;
	}

	// Remove title attribute
	statusBadge.removeAttribute( 'title' );

	// Update status badge class
	const classList = Array.from( statusBadge.classList );
	const oldStatusClass = classList.find( ( cls ) => cls.startsWith( 'edd-status-badge--' ) );
	if ( oldStatusClass ) {
		statusBadge.classList.remove( oldStatusClass );
	}
	statusBadge.classList.add( 'edd-status-badge--success' );
}

/**
 * Removes action buttons except "View Details".
 *
 * @param {HTMLElement} row - The table row.
 */
function cleanupRowActions( row ) {
	const rowActions = row.querySelector( '.row-actions' );
	if ( ! rowActions ) {
		return;
	}

	const allActions = rowActions.querySelectorAll( 'span' );
	allActions.forEach( function ( actionSpan ) {
		const hasViewButton = actionSpan.querySelector( '.edd-acr-view-cart' );
		if ( ! hasViewButton ) {
			actionSpan.remove();
		}
	} );

	// Clean up trailing separator
	cleanupTrailingSeparator( rowActions );
}

/**
 * Removes trailing " | " separator from text without using a backtracking-prone regex.
 *
 * @param {string} text - The text to clean.
 * @return {string} Text with trailing separator removed.
 */
function removeTrailingSeparatorFromText( text ) {
	let s = text.trimEnd();
	if ( s.endsWith( '|' ) ) {
		s = s.slice( 0, -1 ).trimEnd();
	}
	return s;
}

/**
 * Removes trailing separator from view span.
 *
 * @param {HTMLElement} rowActions - The row actions container.
 */
function cleanupTrailingSeparator( rowActions ) {
	const viewSpan = rowActions.querySelector( 'span.view' );
	if ( ! viewSpan ) {
		return;
	}

	const textNodes = Array.from( viewSpan.childNodes ).filter( function ( node ) {
		return node.nodeType === Node.TEXT_NODE;
	} );

	textNodes.forEach( function ( textNode ) {
		textNode.textContent = removeTrailingSeparatorFromText( textNode.textContent );
	} );
}

/**
 * Handles error in row action.
 *
 * @param {HTMLElement} target   - The clicked button.
 * @param {Object}      res      - The response object.
 * @param {Object}      messages - Messages configuration.
 */
function handleError( target, res, messages ) {
	const row = target.closest( 'tr' );
	if ( row ) {
		row.classList.add( 'edd-acr-row-error' );
		setTimeout( function () {
			row.classList.remove( 'edd-acr-row-error' );
		}, 500 );
	}

	console.error( 'ACR admin action failed:', res );
	const errorMessage = res?.message || messages.genericFailure;
	showNotice( errorMessage, messages );
}
