/**
 * Editor-preview “+” controls to append tabs / accordion / card items from the canvas.
 */

import { __ } from '@wordpress/i18n';
import { createDefaultCollectionItem } from './collectionRepeater';

export const TABS_ADD_ATTR = 'data-bm-add-tab';
export const TABS_ADD_SELECTOR = `[${ TABS_ADD_ATTR }]`;
export const ACCORDION_ADD_ATTR = 'data-bm-add-accordion';
export const ACCORDION_ADD_SELECTOR = `[${ ACCORDION_ADD_ATTR }]`;
export const CARDS_ADD_ATTR = 'data-bm-add-card';
export const CARDS_ADD_SELECTOR = `[${ CARDS_ADD_ATTR }]`;

/**
 * @param {Array|null|undefined} fieldSchema
 * @return {object|null}
 */
export function findTabsRepeaterField( fieldSchema ) {
	const fields = Array.isArray( fieldSchema ) ? fieldSchema : [];
	return (
		fields.find(
			( f ) =>
				f &&
				f.type === 'repeater' &&
				( f.itemType === 'tab' || f.key === 'tabs' )
		) || null
	);
}

/**
 * @param {Array|null|undefined} fieldSchema
 * @return {object|null}
 */
export function findAccordionRepeaterField( fieldSchema ) {
	const fields = Array.isArray( fieldSchema ) ? fieldSchema : [];
	return (
		fields.find(
			( f ) =>
				f &&
				f.type === 'repeater' &&
				( f.itemType === 'accordion' ||
					( f.key === 'items' &&
						( f.fields || [] ).some(
							( nested ) => nested?.key === 'accordionTitle'
						) ) )
		) || null
	);
}

/**
 * @param {Array|null|undefined} fieldSchema
 * @return {object|null}
 */
export function findCardsRepeaterField( fieldSchema ) {
	const fields = Array.isArray( fieldSchema ) ? fieldSchema : [];
	return (
		fields.find(
			( f ) =>
				f &&
				f.type === 'repeater' &&
				( f.itemType === 'card' || f.key === 'cards' )
		) || null
	);
}

/**
 * @param {object|null|undefined} field
 * @param {number}                index
 * @return {object}
 */
export function createDefaultTabItem( field = null, index = 0 ) {
	const seeded = createDefaultCollectionItem( field || {}, index );
	if ( ! seeded.tabTitle ) {
		seeded.tabTitle = __( 'New tab', 'joc-blockora-morph' );
	}
	if ( ! seeded.tabContent ) {
		seeded.tabContent = __(
			'Add your tab content here.',
			'joc-blockora-morph'
		);
	}
	if ( seeded.icon == null ) {
		seeded.icon = '';
	}
	if ( ! seeded.iconSize ) {
		seeded.iconSize = '1.25rem';
	}
	return seeded;
}

/**
 * @param {object|null|undefined} field
 * @param {number}                index
 * @return {object}
 */
export function createDefaultAccordionItem( field = null, index = 0 ) {
	const seeded = createDefaultCollectionItem( field || {}, index );
	if ( ! seeded.accordionTitle ) {
		seeded.accordionTitle = __( 'New item', 'joc-blockora-morph' );
	}
	if ( ! seeded.accordionContent ) {
		seeded.accordionContent = __(
			'Add your accordion content here.',
			'joc-blockora-morph'
		);
	}
	if ( seeded.icon == null ) {
		seeded.icon = '';
	}
	if ( ! seeded.iconSize ) {
		seeded.iconSize = '1.25rem';
	}
	return seeded;
}

/**
 * @param {object|null|undefined} field
 * @param {number}                index
 * @return {object}
 */
export function createDefaultCardItem( field = null, index = 0, siblings = [] ) {
	const seeded = createDefaultCollectionItem(
		field || {},
		index,
		siblings
	);
	if ( ! seeded.title ) {
		seeded.title = __( 'New card', 'joc-blockora-morph' );
	}
	if ( ! seeded.description ) {
		seeded.description = __(
			'Add your card description here.',
			'joc-blockora-morph'
		);
	}
	return seeded;
}

/**
 * Build attributes patch that appends one tab.
 *
 * @param {object}                attributes
 * @param {Array|null|undefined}  fieldSchema
 * @return {{ patch: object, newIndex: number, field: object }|null}
 */
export function appendTabToAttributes( attributes, fieldSchema ) {
	const field = findTabsRepeaterField( fieldSchema );
	if ( ! field?.key ) {
		return null;
	}
	const key = field.key;
	const items = Array.isArray( attributes?.[ key ] ) ? attributes[ key ] : [];
	const newIndex = items.length;
	return {
		field,
		newIndex,
		patch: {
			[ key ]: [ ...items, createDefaultTabItem( field, newIndex ) ],
		},
	};
}

/**
 * Build attributes patch that appends one accordion item.
 *
 * @param {object}                attributes
 * @param {Array|null|undefined}  fieldSchema
 * @return {{ patch: object, newIndex: number, field: object }|null}
 */
export function appendAccordionItemToAttributes( attributes, fieldSchema ) {
	const field = findAccordionRepeaterField( fieldSchema );
	if ( ! field?.key ) {
		return null;
	}
	const key = field.key;
	const items = Array.isArray( attributes?.[ key ] ) ? attributes[ key ] : [];
	const newIndex = items.length;
	return {
		field,
		newIndex,
		patch: {
			[ key ]: [
				...items,
				createDefaultAccordionItem( field, newIndex ),
			],
		},
	};
}

/**
 * Build attributes patch that appends one card.
 *
 * @param {object}                attributes
 * @param {Array|null|undefined}  fieldSchema
 * @return {{ patch: object, newIndex: number, field: object }|null}
 */
export function appendCardToAttributes( attributes, fieldSchema ) {
	const field = findCardsRepeaterField( fieldSchema );
	if ( ! field?.key ) {
		return null;
	}
	const key = field.key;
	const items = Array.isArray( attributes?.[ key ] ) ? attributes[ key ] : [];
	const newIndex = items.length;
	return {
		field,
		newIndex,
		patch: {
			[ key ]: [
				...items,
				createDefaultCardItem( field, newIndex, items ),
			],
		},
	};
}

/**
 * @param {EventTarget|null|undefined} el
 * @return {boolean}
 */
export function isTabsAddButtonTarget( el ) {
	return Boolean(
		el && typeof el.closest === 'function' && el.closest( TABS_ADD_SELECTOR )
	);
}

/**
 * @param {EventTarget|null|undefined} el
 * @return {boolean}
 */
export function isAccordionAddButtonTarget( el ) {
	return Boolean(
		el &&
			typeof el.closest === 'function' &&
			el.closest( ACCORDION_ADD_SELECTOR )
	);
}

/**
 * @param {EventTarget|null|undefined} el
 * @return {boolean}
 */
export function isCardsAddButtonTarget( el ) {
	return Boolean(
		el &&
			typeof el.closest === 'function' &&
			el.closest( CARDS_ADD_SELECTOR )
	);
}

/**
 * Inject (or remove) “+” placeholders at the end of each tabs nav in a preview root.
 *
 * @param {ParentNode|null|undefined} root
 * @param {{ enabled?: boolean, fieldSchema?: Array }} [options]
 */
export function injectPreviewTabsAddButtons( root, options = {} ) {
	const enabled = options.enabled !== false;
	if ( ! root || typeof root.querySelectorAll !== 'function' ) {
		return;
	}

	root.querySelectorAll( TABS_ADD_SELECTOR ).forEach( ( el ) => {
		el.remove();
	} );

	if ( ! enabled ) {
		return;
	}

	if (
		options.fieldSchema != null &&
		! findTabsRepeaterField( options.fieldSchema )
	) {
		return;
	}

	const doc = root.ownerDocument || document;
	const navs = root.querySelectorAll( '.bm-tabs__nav' );
	navs.forEach( ( nav ) => {
		if ( nav.querySelector( TABS_ADD_SELECTOR ) ) {
			return;
		}
		const btn = doc.createElement( 'button' );
		btn.type = 'button';
		btn.className = 'bm-tabs__add';
		btn.setAttribute( TABS_ADD_ATTR, '1' );
		btn.setAttribute(
			'aria-label',
			__( 'Add tab', 'joc-blockora-morph' )
		);
		btn.title = __( 'Add tab', 'joc-blockora-morph' );
		btn.innerHTML =
			'<span class="dashicons dashicons-plus-alt2" aria-hidden="true"></span>';
		nav.appendChild( btn );
	} );
}

/**
 * Inject (or remove) “+” at the end of each accordion list in a preview root.
 *
 * @param {ParentNode|null|undefined} root
 * @param {{ enabled?: boolean, fieldSchema?: Array }} [options]
 */
export function injectPreviewAccordionAddButtons( root, options = {} ) {
	const enabled = options.enabled !== false;
	if ( ! root || typeof root.querySelectorAll !== 'function' ) {
		return;
	}

	root.querySelectorAll( ACCORDION_ADD_SELECTOR ).forEach( ( el ) => {
		el.remove();
	} );

	if ( ! enabled ) {
		return;
	}

	if (
		options.fieldSchema != null &&
		! findAccordionRepeaterField( options.fieldSchema )
	) {
		return;
	}

	const doc = root.ownerDocument || document;
	const lists = root.querySelectorAll( '.bm-accordion__list' );
	lists.forEach( ( list ) => {
		if ( list.querySelector( ACCORDION_ADD_SELECTOR ) ) {
			return;
		}
		const btn = doc.createElement( 'button' );
		btn.type = 'button';
		btn.className = 'bm-accordion__add';
		btn.setAttribute( ACCORDION_ADD_ATTR, '1' );
		btn.setAttribute(
			'aria-label',
			__( 'Add item', 'joc-blockora-morph' )
		);
		btn.title = __( 'Add item', 'joc-blockora-morph' );
		btn.innerHTML =
			'<span class="dashicons dashicons-plus-alt2" aria-hidden="true"></span>';
		list.appendChild( btn );
	} );
}

/**
 * Inject (or remove) dashed “+” card cell at the end of each cards grid.
 *
 * @param {ParentNode|null|undefined} root
 * @param {{ enabled?: boolean, fieldSchema?: Array }} [options]
 */
export function injectPreviewCardsAddButtons( root, options = {} ) {
	const enabled = options.enabled !== false;
	if ( ! root || typeof root.querySelectorAll !== 'function' ) {
		return;
	}

	root.querySelectorAll( CARDS_ADD_SELECTOR ).forEach( ( el ) => {
		el.remove();
	} );

	if ( ! enabled ) {
		return;
	}

	if (
		options.fieldSchema != null &&
		! findCardsRepeaterField( options.fieldSchema )
	) {
		return;
	}

	const doc = root.ownerDocument || document;
	const grids = root.querySelectorAll( '.bm-cards__grid' );
	grids.forEach( ( grid ) => {
		if ( grid.querySelector( CARDS_ADD_SELECTOR ) ) {
			return;
		}
		const btn = doc.createElement( 'button' );
		btn.type = 'button';
		btn.className = 'bm-cards__add';
		btn.setAttribute( CARDS_ADD_ATTR, '1' );
		btn.setAttribute(
			'aria-label',
			__( 'Add card', 'joc-blockora-morph' )
		);
		btn.title = __( 'Add card', 'joc-blockora-morph' );
		btn.innerHTML =
			'<span class="dashicons dashicons-plus-alt2" aria-hidden="true"></span>';
		grid.appendChild( btn );
	} );
}

/**
 * Shared editor-preview styles for the add-tab / add-item / add-card controls.
 */
export const PREVIEW_TABS_ADD_CSS = `
.bm-tabs__add,
.bm-accordion__add,
.bm-cards__add{
	display:inline-flex;
	align-items:center;
	justify-content:center;
	align-self:flex-end;
	flex:0 0 auto;
	box-sizing:border-box;
	min-width:2.35rem;
	min-height:2.35rem;
	margin:0 0 0 0.15rem;
	padding:0.35rem 0.55rem;
	border:1px dashed rgba(15,23,42,.28);
	border-radius:8px;
	background:rgba(255,255,255,.72);
	color:#64748b;
	cursor:pointer;
	line-height:1;
	box-shadow:none;
	position:relative;
	z-index:6;
}
.bm-accordion__add{
	align-self:stretch;
	width:100%;
	margin:0.15rem 0 0;
}
.bm-cards__add{
	align-self:stretch;
	width:100%;
	min-height:10rem;
	margin:0;
	padding:1.25rem;
	border-radius:var(--bm-card-border-radius, 8px);
}
.bm-tabs__add:hover,
.bm-tabs__add:focus-visible,
.bm-accordion__add:hover,
.bm-accordion__add:focus-visible,
.bm-cards__add:hover,
.bm-cards__add:focus-visible{
	color:#0f172a;
	border-color:rgba(15,23,42,.5);
	background:#fff;
	outline:2px solid rgba(53,37,205,.35);
	outline-offset:2px;
}
.bm-tabs__add .dashicons,
.bm-accordion__add .dashicons,
.bm-cards__add .dashicons{
	width:18px;
	height:18px;
	font-size:18px;
	line-height:1;
	display:block;
}
.bm-cards__add .dashicons{
	width:28px;
	height:28px;
	font-size:28px;
}
`;
