/**
 * File Path: assets/js/adminjs/mbs-admin-arc.js
 *
 * ARC Metabox JS -- Pre-Release / ARC panel
 *
 * Handles:
 *   - Add / remove reviewer rows (clone hidden template row)
 *   - Enable / disable URL sub-repeater (Add URL btn + URL fields) based on
 *     review_posted checkbox state; auto-adds first URL row on check
 *   - Add / remove individual review URL rows per reviewer
 *   - Export (XLSX / CSV / JSON) via hidden-form POST with spinner feedback
 *
 * Depends on: MbsArc (localized by MBS_Metabox_Arc_Render::enqueue())
 *
 * Selector reference (must match templates/admin/metabox-arc.php):
 *   .mbs-arc-fields            -- outer wrapper div
 *   .mbs-arc-row-template      -- hidden clone-source reviewer row (class, not ID)
 *   #mbs-arc-reviewer-rows     -- live rows container
 *   .mbs-arc-reviewer-row      -- each reviewer row (includes template row)
 *   .mbs-arc-posted-cb         -- "Review posted" checkbox
 *   .mbs-arc-url-repeater      -- URL sub-repeater wrapper
 *   .mbs-arc-url-list          -- container for live URL rows
 *   .mbs-arc-url-row           -- each URL row
 *   .mbs-arc-url-row-template  -- hidden clone-source URL row (inside reviewer row)
 *   .mbs-arc-url-field         -- review URL input
 *   .mbs-arc-add-url           -- Add Review URL button (per reviewer row)
 *   .mbs-arc-remove-url        -- Remove URL button (per URL row)
 *   .mbs-arc-add-row           -- Add Reviewer button
 *   .mbs-arc-remove-row        -- Remove button inside each reviewer row
 *   .mbs-arc-export-btn        -- Export buttons (data-format="xlsx|csv|json")
 *
 * @package MyBookShowroom
 * @since   2.1.0
 */
/* global MbsArc */
( function ( $ ) {
	'use strict';

	var ARC = {

		init: function () {
			var $wrap = $( '.mbs-arc-fields' );
			if ( ! $wrap.length ) {
				return;
			}

			// Wire existing (saved) rows on page load -- exclude the hidden template row.
			ARC.wireRows( $wrap.find( '.mbs-arc-reviewer-row:not(.mbs-arc-row-template)' ) );

			// Add reviewer row.
			$( document ).on( 'click', '.mbs-arc-add-row', function ( e ) {
				e.preventDefault();
				ARC.addRow();
			} );

			// Remove reviewer row.
			$( document ).on( 'click', '.mbs-arc-remove-row', function ( e ) {
				e.preventDefault();
				$( this ).closest( '.mbs-arc-reviewer-row' ).remove();
				ARC.updateRowIndexes();
			} );

			// Add URL row within a reviewer row.
			$( document ).on( 'click', '.mbs-arc-add-url', function ( e ) {
				e.preventDefault();
				ARC.addUrlRow( $( this ).closest( '.mbs-arc-reviewer-row' ) );
			} );

			// Remove URL row.
			$( document ).on( 'click', '.mbs-arc-remove-url', function ( e ) {
				e.preventDefault();
				$( this ).closest( '.mbs-arc-url-row' ).remove();
			} );

			// Export buttons.
			$( document ).on( 'click', '.mbs-arc-export-btn', function ( e ) {
				e.preventDefault();
				var fmt = $( this ).data( 'format' );
				ARC.doExport( fmt, $( this ) );
			} );
		},

		/**
		 * Wire a set of reviewer rows.
		 *
		 * @param {jQuery} $rows
		 */
		wireRows: function ( $rows ) {
			$rows.each( function () {
				ARC.wireRow( $( this ) );
			} );
		},

		/**
		 * Wire a single reviewer row.
		 * Binds the review_posted checkbox to the URL sub-repeater enable/disable state.
		 *
		 * @param {jQuery} $row
		 */
		wireRow: function ( $row ) {
			var $checkbox = $row.find( '.mbs-arc-posted-cb' );

			// Set initial state.
			ARC.syncUrlState( $row, $checkbox );

			// Update on change.
			$checkbox.on( 'change', function () {
				ARC.syncUrlState( $row, $( this ) );
			} );
		},

		/**
		 * Enable or disable the URL sub-repeater (URL inputs + Add URL button)
		 * based on the review_posted checkbox state.
		 * When newly checked with no URL rows, auto-adds a first URL row.
		 *
		 * @param {jQuery} $row      Reviewer row element.
		 * @param {jQuery} $checkbox The review_posted checkbox.
		 */
		syncUrlState: function ( $row, $checkbox ) {
			var isPosted  = $checkbox.is( ':checked' );
			var $urlList  = $row.find( '.mbs-arc-url-list' );
			var $addBtn   = $row.find( '.mbs-arc-add-url' );

			// Enable/disable all live URL inputs (exclude hidden template row).
			var $liveFields = $urlList.find( '.mbs-arc-url-row:not(.mbs-arc-url-row-template) .mbs-arc-url-field' );
			$liveFields.prop( 'disabled', ! isPosted );
			$addBtn.prop( 'disabled', ! isPosted );

			// Auto-add first URL row when review_posted is newly checked and no rows exist.
			if ( isPosted && 0 === $urlList.find( '.mbs-arc-url-row:not(.mbs-arc-url-row-template)' ).length ) {
				ARC.addUrlRow( $row );
			}
		},

		/**
		 * Clone the hidden URL row template within a reviewer row, make it
		 * visible, enable the URL input, and append it to the URL list.
		 *
		 * @param {jQuery} $reviewerRow The reviewer row containing this URL repeater.
		 */
		addUrlRow: function ( $reviewerRow ) {
			var $urlTemplate = $reviewerRow.find( '.mbs-arc-url-row-template' );
			if ( ! $urlTemplate.length ) {
				return;
			}
			var $newUrl = $urlTemplate.clone( false )
				.removeClass( 'mbs-arc-url-row-template' )
				.removeAttr( 'aria-hidden' )
				.css( 'display', '' );
			$newUrl.find( '.mbs-arc-url-field' ).prop( 'disabled', false );
			$reviewerRow.find( '.mbs-arc-url-list' ).append( $newUrl );
			$newUrl.find( '.mbs-arc-url-field' ).trigger( 'focus' );
		},

		/**
		 * Clone the hidden template reviewer row, replace __IDX__ placeholders,
		 * append to the live rows container, and wire the new row.
		 */
		addRow: function () {
			var $template = $( '.mbs-arc-row-template' );
			if ( ! $template.length ) {
				return;
			}

			// Index = number of live rows (template row excluded).
			var idx = $( '#mbs-arc-reviewer-rows .mbs-arc-reviewer-row:not(.mbs-arc-row-template)' ).length;

			// Clone, strip template marker, make visible.
			var $row = $template.clone( false )
				.removeClass( 'mbs-arc-row-template' )
				.removeAttr( 'aria-hidden' )
				.css( 'display', '' );

			// Replace __IDX__ in all name attributes (reviewer fields + nested URL template).
			$row.find( '[name]' ).each( function () {
				var newName = $( this ).attr( 'name' ).replace( /__IDX__/g, idx );
				$( this ).attr( 'name', newName );
			} );

			$( '#mbs-arc-reviewer-rows' ).append( $row );
			ARC.wireRow( $row );
			ARC.updateRowIndexes();
		},

		/**
		 * Re-index all live reviewer rows so array-named inputs stay sequential
		 * after any add or remove.
		 *
		 * Works for both reviewer-level fields (mbs_arc_reviewers[N][field])
		 * and nested URL fields (mbs_arc_reviewers[N][review_urls][]) because
		 * the regex /\[\d+\]/ matches only numeric-index brackets, leaving the
		 * empty [] on review_urls untouched.
		 */
		updateRowIndexes: function () {
			$( '#mbs-arc-reviewer-rows .mbs-arc-reviewer-row:not(.mbs-arc-row-template)' ).each( function ( i ) {
				$( this ).find( '[name]' ).each( function () {
					var newName = $( this ).attr( 'name' ).replace( /\[\d+\]/g, '[' + i + ']' );
					$( this ).attr( 'name', newName );
				} );
			} );
		},

		/**
		 * Trigger an export download via hidden form POST.
		 * The browser handles the file download without page navigation.
		 *
		 * @param {string} fmt  'xlsx' | 'csv' | 'json'
		 * @param {jQuery} $btn Clicked button element.
		 */
		doExport: function ( fmt, $btn ) {
			var postId = MbsArc.postId;
			var nonce  = MbsArc.exportNonce;

			if ( ! postId || ! nonce ) {
				return;
			}

			// Show spinner.
			var $spinner = $btn.siblings( '.spinner' );
			$spinner.addClass( 'is-active' );
			$btn.prop( 'disabled', true );

			// Build hidden form and submit (triggers download).
			var action = 'mbs_export_arc_reviewers' + ( fmt === 'json' ? '_json' : '' );
			var $form  = $( '<form>', { method: 'POST', action: MbsArc.ajaxUrl } );
			$form.append( $( '<input>', { type: 'hidden', name: 'action',  value: action  } ) );
			$form.append( $( '<input>', { type: 'hidden', name: 'post_id', value: postId  } ) );
			$form.append( $( '<input>', { type: 'hidden', name: 'format',  value: fmt     } ) );
			$form.append( $( '<input>', { type: 'hidden', name: 'nonce',   value: nonce   } ) );
			$( 'body' ).append( $form );
			$form.submit();
			$form.remove();

			// Re-enable after short delay (download has no callback).
			setTimeout( function () {
				$spinner.removeClass( 'is-active' );
				$btn.prop( 'disabled', false );
			}, 2000 );
		}
	};

	$( document ).ready( function () {
		ARC.init();
	} );

} )( jQuery );
