/**
 * File Path: assets/js/adminjs/mbs-archive-import-export.js
 *
 * MBS Archive Import / Export — Admin JS
 *
 * Drives the Archive Import panel on the Import/Export tab (ZIP scenario card).
 *
 * Uses MBSImportProgress (mbs-import-progress.js) for the vanishing-message
 * progress UX: one current-activity line replaces itself per step; warnings
 * persist below; on success the bar fades after 2.5 s.
 *
 * Import flow:
 *   Phase A -- Upload:  POST the ZIP to mbs_archive_import_start.
 *                        Response: { token, total, taxonomy }.
 *   Phase B -- Hydrate: Fire mbs_archive_import_book for index 0..total-1.
 *                        Progress bar fills from 0 to 50%.
 *   Phase C -- Media:   Fire mbs_archive_import_media for index 0..total-1.
 *                        Progress bar fills from 50% to 100%.
 *
 * Depends on: jQuery, MBS_Archive (wp_localize_script), wp-i18n,
 *             MBSImportProgress (mbs-import-progress.js).
 *
 * @package MyBookShowroom
 * @since   1.0.0
 */

/* global MBS_Archive, MBSImportProgress, jQuery */
( function ( $, __ ) {
	'use strict';

	// -------------------------------------------------------------------------
	// Selectors
	// -------------------------------------------------------------------------
	var SEL = {
		importZone     : '#mbs-archive-import-drop-zone',
		importFileInput: '#mbs-archive-import-file',
		importFilename : '#mbs-archive-import-filename',
		importStartBtn : '#mbs-archive-import-start-btn',
	};

	// -------------------------------------------------------------------------
	// State
	// -------------------------------------------------------------------------
	var state = {
		file   : null,
		token  : '',
		total  : 0,
		titles : {},  // index (int) => title (string) cache
		errors : [],
		running: false,
	};

	/** @type {Object} MBSImportProgress instance */
	var progress = null;

	// -------------------------------------------------------------------------
	// Helpers
	// -------------------------------------------------------------------------

	/**
	 * Enable or disable the import start button and update running state.
	 *
	 * @param {boolean} locked
	 */
	function lockImport( locked ) {
		$( SEL.importStartBtn ).prop( 'disabled', locked );
		state.running = locked;
	}

	// -------------------------------------------------------------------------
	// File selection
	// -------------------------------------------------------------------------

	function initFileSelection() {
		// Click the hidden file input when the drop zone is clicked.
		// Guard: if the click target is already the file input, do nothing --
		// the synthetic click we fire below bubbles back up to the zone and
		// would cause infinite recursion without this check.
		$( document ).on( 'click', SEL.importZone, function ( e ) {
			if ( $( e.target ).is( SEL.importFileInput ) ) {
				return;
			}
			$( SEL.importFileInput ).trigger( 'click' );
		} );

		// File input change handler -- bound directly to avoid Plupload
		// event interference that occurs with document-level delegation.
		$( SEL.importFileInput ).on( 'change', function () {
			var file = this.files && this.files[0] ? this.files[0] : null;
			handleFileSelected( file );
		} );

		// Drag and drop onto the drop zone.
		$( document ).on( 'dragover', SEL.importZone, function ( e ) {
			e.preventDefault();
			$( this ).addClass( 'drag-over' );
		} );
		$( document ).on( 'dragleave drop', SEL.importZone, function ( e ) {
			e.preventDefault();
			$( this ).removeClass( 'drag-over' );
			if ( e.type === 'drop' ) {
				var file = e.originalEvent.dataTransfer.files[0] || null;
				handleFileSelected( file );
			}
		} );
	}

	/**
	 * Accept a File object, validate MIME/extension, and update UI state.
	 *
	 * @param {File|null} file
	 */
	function handleFileSelected( file ) {
		if ( ! file ) {
			return;
		}
		if ( file.type !== 'application/zip' && ! file.name.match( /\.zip$/i ) ) {
			progress.reset();
			progress.failed(
				__( 'Please select a valid ZIP archive (.zip).', 'my-book-showroom' )
			);
			return;
		}
		state.file = file;
		$( SEL.importFilename ).text( file.name );
		$( SEL.importStartBtn ).prop( 'disabled', false );
		progress.reset();
	}

	// -------------------------------------------------------------------------
	// Import -- Phase A: upload + prepare
	// -------------------------------------------------------------------------

	function startImport() {
		if ( ! state.file || state.running ) {
			return;
		}
		lockImport( true );
		progress.reset();
		progress.show();
		progress.setBar( 2 );
		progress.setMessage( __( 'Uploading archive\u2026', 'my-book-showroom' ) );

		var formData = new FormData();
		formData.append( 'action',       'mbs_archive_import_start' );
		formData.append( 'nonce',        MBS_Archive.nonce );
		formData.append( 'archive_file', state.file );

		$.ajax( {
			url         : MBS_Archive.ajaxUrl,
			type        : 'POST',
			data        : formData,
			processData : false,
			contentType : false,
			success     : function ( resp ) {
				if ( ! resp.success ) {
					importFailed( resp.data ? resp.data.message
						: __( 'Upload failed.', 'my-book-showroom' ) );
					return;
				}
				var d = resp.data;
				state.token  = d.token;
				state.total  = d.total;
				state.titles = {};
				state.errors = [];

				progress.setBar( 5 );
				progress.setMessage(
					d.total + ' ' +
					__( 'book(s) found in archive.', 'my-book-showroom' )
				);

				if ( state.total === 0 ) {
					importComplete();
					return;
				}
				hydrateBook( 0 );
			},
			error : function () {
				importFailed( __( 'Network error during upload.', 'my-book-showroom' ) );
			},
		} );
	}

	// -------------------------------------------------------------------------
	// Import -- Phase B: hydrate books
	// -------------------------------------------------------------------------

	/**
	 * Hydrate the book at the given index.
	 *
	 * @param {number} index  Zero-based book index.
	 */
	function hydrateBook( index ) {
		var pct = Math.round( ( index / ( state.total * 2 ) ) * 100 );
		progress.setBar( pct );
		progress.setMessage(
			__( 'Installing book', 'my-book-showroom' ) + ' ' +
			( index + 1 ) + ' ' +
			__( 'of', 'my-book-showroom' ) + ' ' + state.total + '\u2026'
		);

		$.post( MBS_Archive.ajaxUrl, {
			action : 'mbs_archive_import_book',
			nonce  : MBS_Archive.nonce,
			token  : state.token,
			index  : index,
		}, function ( resp ) {
			if ( ! resp.success ) {
				importFailed( resp.data ? resp.data.message
					: __( 'Hydration failed.', 'my-book-showroom' ) );
				return;
			}
			var d = resp.data;

			// Cache the title for the media pass.
			var title = d.title || ( __( 'Book', 'my-book-showroom' ) + ' #' + ( index + 1 ) );
			state.titles[ index ] = title;

			if ( d.post_id > 0 ) {
				progress.setMessage(
					'\u2713 \u201c' + title + '\u201d (' + ( index + 1 ) +
					' ' + __( 'of', 'my-book-showroom' ) + ' ' + state.total + ')'
				);
			} else {
				progress.setMessage(
					'\u21b7 \u201c' + title + '\u201d \u2014 ' +
					__( 'skipped (duplicate or error)', 'my-book-showroom' )
				);
			}

			if ( d.errors && d.errors.length ) {
				$.each( d.errors, function ( i, msg ) {
					progress.addWarning( msg );
					state.errors.push( msg );
				} );
			}

			if ( d.done ) {
				sideloadMedia( 0 );
			} else {
				hydrateBook( index + 1 );
			}
		} ).fail( function () {
			importFailed( __( 'Network error during book import.', 'my-book-showroom' ) );
		} );
	}

	// -------------------------------------------------------------------------
	// Import -- Phase C: sideload media
	// -------------------------------------------------------------------------

	/**
	 * Sideload media for the book at the given index.
	 *
	 * @param {number} index  Zero-based book index.
	 */
	function sideloadMedia( index ) {
		var pct   = Math.round( ( ( state.total + index ) / ( state.total * 2 ) ) * 100 );
		var title = state.titles[ index ] ||
			( __( 'book', 'my-book-showroom' ) + ' ' + ( index + 1 ) );
		progress.setBar( pct );
		progress.setMessage(
			__( 'Sideloading media for', 'my-book-showroom' ) +
			' \u201c' + title + '\u201d\u2026'
		);

		$.post( MBS_Archive.ajaxUrl, {
			action : 'mbs_archive_import_media',
			nonce  : MBS_Archive.nonce,
			token  : state.token,
			index  : index,
		}, function ( resp ) {
			if ( ! resp.success ) {
				// Media errors are non-fatal -- log and continue.
				var msg = resp.data ? resp.data.message
					: __( 'Media sideload error.', 'my-book-showroom' );
				progress.addWarning( msg );
				state.errors.push( msg );
				// Guard: if this was the last book, complete rather than
				// looping past a valid index (e.g. session expiry on final req).
				if ( index + 1 >= state.total ) {
					importComplete();
					return;
				}
			} else {
				var d = resp.data;
				if ( d.errors && d.errors.length ) {
					$.each( d.errors, function ( i, errMsg ) {
						progress.addWarning( errMsg );
						state.errors.push( errMsg );
					} );
				}
				if ( d.done ) {
					importComplete();
					return;
				}
			}
			sideloadMedia( index + 1 );
		} ).fail( function () {
			// Network errors during media are non-fatal -- move on.
			var msg = __( 'Network error during media sideload for book', 'my-book-showroom' ) +
				' ' + ( index + 1 );
			progress.addWarning( msg );
			state.errors.push( msg );
			if ( index + 1 >= state.total ) {
				importComplete();
			} else {
				sideloadMedia( index + 1 );
			}
		} );
	}

	// -------------------------------------------------------------------------
	// Import -- completion / failure
	// -------------------------------------------------------------------------

	function importComplete() {
		var summary;
		if ( state.errors.length ) {
			summary =
				state.total + ' ' +
				__( 'book(s) imported with', 'my-book-showroom' ) + ' ' +
				state.errors.length + ' ' +
				__( 'warning(s). See details above.', 'my-book-showroom' );
		} else {
			summary =
				state.total + ' ' +
				__( 'book(s) imported successfully. \u2713', 'my-book-showroom' );
		}
		lockImport( false );
		progress.complete( summary );
	}

	function importFailed( msg ) {
		lockImport( false );
		progress.failed( msg );
	}

	// -------------------------------------------------------------------------
	// Start button
	// -------------------------------------------------------------------------

	function initImportButton() {
		$( document ).on( 'click', SEL.importStartBtn, function ( e ) {
			e.preventDefault();
			startImport();
		} );
	}

	// -------------------------------------------------------------------------
	// Init
	// -------------------------------------------------------------------------

	$( function () {
		progress = MBSImportProgress.create( {
			barWrap    : document.getElementById( 'mbs-archive-import-progress' ),
			barFill    : document.getElementById( 'mbs-archive-import-bar-fill' ),
			msgArea    : document.getElementById( 'mbs-archive-import-log' ),
			statusArea : document.getElementById( 'mbs-archive-import-status' ),
		} );
		initFileSelection();
		initImportButton();
	} );

} )( jQuery, wp.i18n.__ );
