/**
 * Wohno listings — card image gallery + detail modal.
 *
 * Buildless, dependency-free. The card carries its full detail payload in a
 * `data-wohno-listing` attribute (built server-side from the list response), so
 * the modal opens instantly without an extra API call. Without JS the card link
 * falls back to the canonical detail page on wohno.de.
 */
( function () {
	'use strict';

	var L = window.wohnoListings || {};
	function t( key, fallback ) {
		return Object.prototype.hasOwnProperty.call( L, key ) && L[ key ] ? L[ key ] : fallback;
	}

	function el( tag, className, text ) {
		var node = document.createElement( tag );
		if ( className ) {
			node.className = className;
		}
		if ( undefined !== text && null !== text ) {
			node.textContent = text;
		}
		return node;
	}

	/* ----------------------------- Card galleries ----------------------------- */

	function initCard( card ) {
		card.setAttribute( 'data-wohno-ready', '' );

		var imgs = card.querySelectorAll( '.wohno-card__gallery .wohno-card__img' );
		var dots = card.querySelectorAll( '[data-wohno-dot]' );
		var index = 0;

		function show( i ) {
			if ( ! imgs.length ) {
				return;
			}
			index = ( i + imgs.length ) % imgs.length;
			imgs.forEach( function ( im, n ) {
				im.classList.toggle( 'is-active', n === index );
			} );
			dots.forEach( function ( d, n ) {
				d.classList.toggle( 'is-active', n === index );
			} );
		}

		bindStop( card.querySelector( '[data-wohno-prev]' ), function () {
			show( index - 1 );
		} );
		bindStop( card.querySelector( '[data-wohno-next]' ), function () {
			show( index + 1 );
		} );
		dots.forEach( function ( dot ) {
			bindStop( dot, function () {
				show( parseInt( dot.getAttribute( 'data-wohno-dot' ), 10 ) || 0 );
			} );
		} );

		var data = parsePayload( card );
		function open( e ) {
			if ( e ) {
				e.preventDefault();
			}
			if ( data ) {
				openModal( data );
			}
		}

		var link = card.querySelector( '[data-wohno-open]' );
		if ( link ) {
			link.addEventListener( 'click', open );
		}
		var media = card.querySelector( '.wohno-card__media' );
		if ( media ) {
			media.addEventListener( 'click', function ( e ) {
				if ( e.target.closest( '[data-wohno-prev],[data-wohno-next],[data-wohno-dot]' ) ) {
					return;
				}
				open( e );
			} );
		}
	}

	function bindStop( node, fn ) {
		if ( ! node ) {
			return;
		}
		node.addEventListener( 'click', function ( e ) {
			e.preventDefault();
			e.stopPropagation();
			fn();
		} );
	}

	function parsePayload( card ) {
		try {
			return JSON.parse( card.getAttribute( 'data-wohno-listing' ) || 'null' );
		} catch ( e ) {
			return null;
		}
	}

	/* -------------------------------- Modal ---------------------------------- */

	var modal = null;
	var modalImg = null;
	var modalDots = null;
	var modalImages = [];
	var modalIndex = 0;
	var lastFocus = null;

	function buildModal() {
		modal = el( 'div', 'wohno-modal' );
		modal.setAttribute( 'role', 'dialog' );
		modal.setAttribute( 'aria-modal', 'true' );
		modal.hidden = true;

		var backdrop = el( 'div', 'wohno-modal__backdrop' );
		backdrop.setAttribute( 'data-close', '' );

		var dialog = el( 'div', 'wohno-modal__dialog' );

		var close = el( 'button', 'wohno-modal__close', '×' );
		close.type = 'button';
		close.setAttribute( 'data-close', '' );
		close.setAttribute( 'aria-label', t( 'close', 'Schließen' ) );

		var media = el( 'div', 'wohno-modal__media' );
		modalImg = el( 'img', 'wohno-modal__img' );
		modalImg.alt = '';
		var prev = el( 'button', 'wohno-modal__nav wohno-modal__nav--prev', '‹' );
		prev.type = 'button';
		prev.setAttribute( 'aria-label', t( 'prev', 'Zurück' ) );
		var next = el( 'button', 'wohno-modal__nav wohno-modal__nav--next', '›' );
		next.type = 'button';
		next.setAttribute( 'aria-label', t( 'next', 'Weiter' ) );
		modalDots = el( 'div', 'wohno-modal__dots' );
		media.appendChild( modalImg );
		media.appendChild( prev );
		media.appendChild( next );
		media.appendChild( modalDots );

		var body = el( 'div', 'wohno-modal__body' );

		dialog.appendChild( close );
		dialog.appendChild( media );
		dialog.appendChild( body );
		modal.appendChild( backdrop );
		modal.appendChild( dialog );
		document.body.appendChild( modal );

		modal.addEventListener( 'click', function ( e ) {
			if ( e.target.hasAttribute && e.target.hasAttribute( 'data-close' ) ) {
				closeModal();
			}
		} );
		prev.addEventListener( 'click', function () {
			showSlide( modalIndex - 1 );
		} );
		next.addEventListener( 'click', function () {
			showSlide( modalIndex + 1 );
		} );
		document.addEventListener( 'keydown', function ( e ) {
			if ( modal.hidden ) {
				return;
			}
			if ( 'Escape' === e.key ) {
				closeModal();
			} else if ( 'ArrowLeft' === e.key ) {
				showSlide( modalIndex - 1 );
			} else if ( 'ArrowRight' === e.key ) {
				showSlide( modalIndex + 1 );
			} else if ( 'Tab' === e.key ) {
				trapFocus( e );
			}
		} );

		modal._body = body;
		modal._nav = [ prev, next ];
	}

	function showSlide( i ) {
		if ( ! modalImages.length ) {
			return;
		}
		modalIndex = ( i + modalImages.length ) % modalImages.length;
		modalImg.src = modalImages[ modalIndex ].url;
		modalImg.alt = modalImages[ modalIndex ].alt || '';
		Array.prototype.forEach.call( modalDots.children, function ( d, n ) {
			d.classList.toggle( 'is-active', n === modalIndex );
		} );
	}

	function fact( label, value ) {
		if ( ! value ) {
			return null;
		}
		var item = el( 'div', 'wohno-modal__fact' );
		item.appendChild( el( 'span', 'wohno-modal__fact-label', label ) );
		item.appendChild( el( 'span', 'wohno-modal__fact-value', value ) );
		return item;
	}

	function openModal( d ) {
		if ( ! modal ) {
			buildModal();
		}
		lastFocus = document.activeElement;

		// Media.
		modalImages = Array.isArray( d.images ) ? d.images : [];
		modalDots.textContent = '';
		var hasGallery = modalImages.length > 1;
		modal._nav[ 0 ].style.display = hasGallery ? '' : 'none';
		modal._nav[ 1 ].style.display = hasGallery ? '' : 'none';
		if ( modalImages.length ) {
			modalImages.forEach( function ( img, n ) {
				var dot = el( 'button', 'wohno-modal__dot' + ( 0 === n ? ' is-active' : '' ) );
				dot.type = 'button';
				dot.addEventListener( 'click', function () {
					showSlide( n );
				} );
				modalDots.appendChild( dot );
			} );
			showSlide( 0 );
			modalImg.style.display = '';
		} else {
			modalImg.removeAttribute( 'src' );
			modalImg.style.display = 'none';
		}

		// Body.
		var body = modal._body;
		body.textContent = '';

		if ( d.price ) {
			var price = el( 'div', 'wohno-modal__price' );
			price.appendChild( el( 'span', 'wohno-modal__price-value', d.price ) );
			if ( d.priceNote ) {
				price.appendChild( el( 'span', 'wohno-modal__price-note', ' · ' + d.priceNote ) );
			}
			body.appendChild( price );
		}

		body.appendChild( el( 'h2', 'wohno-modal__title', d.title || '' ) );
		if ( d.address || d.place ) {
			body.appendChild( el( 'p', 'wohno-modal__address', d.address || d.place ) );
		}

		var facts = el( 'div', 'wohno-modal__facts' );
		[
			fact( t( 'rooms', 'Zimmer' ), d.rooms ),
			fact( t( 'bedrooms', 'Schlafzimmer' ), d.bedrooms ),
			fact( t( 'bathrooms', 'Badezimmer' ), d.bathrooms ),
			fact( t( 'area', 'Wohnfläche' ), d.area ),
			fact( t( 'type', 'Objekttyp' ), d.type ),
			fact( t( 'available', 'Verfügbar ab' ), d.available )
		].forEach( function ( f ) {
			if ( f ) {
				facts.appendChild( f );
			}
		} );
		if ( facts.children.length ) {
			body.appendChild( facts );
		}

		// Cost breakdown (Kaltmiete, Nebenkosten, Warmmiete, Kaution …).
		if ( Array.isArray( d.costs ) && d.costs.length ) {
			body.appendChild( el( 'h3', 'wohno-modal__subtitle', t( 'costsTitle', 'Kosten' ) ) );
			var costs = el( 'dl', 'wohno-modal__costs' );
			d.costs.forEach( function ( row ) {
				costs.appendChild( el( 'dt', 'wohno-modal__cost-label', row.label ) );
				costs.appendChild( el( 'dd', 'wohno-modal__cost-value', row.value ) );
			} );
			body.appendChild( costs );
		}

		if ( d.description ) {
			body.appendChild( el( 'h3', 'wohno-modal__subtitle', t( 'descriptionTitle', 'Beschreibung' ) ) );
			var descEl = el( 'p', 'wohno-modal__description', d.description );
			body.appendChild( descEl );
			// Long descriptions are sent as a teaser — fetch the full text on open.
			if ( false === d.descriptionFull && d.id ) {
				loadFullDescription( d.id, descEl );
			}
		}

		var actions = el( 'div', 'wohno-modal__actions' );
		if ( d.url ) {
			var apply = el( 'a', 'wohno-modal__btn wohno-modal__btn--primary', t( 'apply', 'Jetzt bewerben' ) );
			apply.href = d.url;
			apply.target = '_blank';
			apply.rel = 'noopener';
			var view = el( 'a', 'wohno-modal__btn wohno-modal__btn--ghost', t( 'view', 'Vollständig ansehen' ) );
			view.href = d.url;
			view.target = '_blank';
			view.rel = 'noopener';
			actions.appendChild( apply );
			actions.appendChild( view );
		}
		body.appendChild( actions );

		modal.hidden = false;
		document.body.classList.add( 'wohno-modal-open' );
		var first = modal.querySelector( '.wohno-modal__close' );
		if ( first ) {
			first.focus();
		}
	}

	function loadFullDescription( id, target ) {
		if ( ! L.ajaxUrl || ! L.detailAction ) {
			return;
		}
		target.classList.add( 'wohno-modal__description--loading' );

		var body = new URLSearchParams();
		body.set( 'action', L.detailAction );
		body.set( 'nonce', L.detailNonce || '' );
		body.set( 'id', id );

		fetch( L.ajaxUrl, {
			method: 'POST',
			credentials: 'same-origin',
			headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
			body: body.toString(),
		} )
			.then( function ( r ) {
				return r.json();
			} )
			.then( function ( res ) {
				target.classList.remove( 'wohno-modal__description--loading' );
				if ( res && res.success && res.data && res.data.description ) {
					target.textContent = res.data.description;
				}
			} )
			.catch( function () {
				target.classList.remove( 'wohno-modal__description--loading' );
			} );
	}

	function closeModal() {
		if ( ! modal ) {
			return;
		}
		modal.hidden = true;
		document.body.classList.remove( 'wohno-modal-open' );
		if ( lastFocus && lastFocus.focus ) {
			lastFocus.focus();
		}
	}

	function trapFocus( e ) {
		var focusable = modal.querySelectorAll( 'a[href], button:not([disabled])' );
		if ( ! focusable.length ) {
			return;
		}
		var first = focusable[ 0 ];
		var last = focusable[ focusable.length - 1 ];
		if ( e.shiftKey && document.activeElement === first ) {
			e.preventDefault();
			last.focus();
		} else if ( ! e.shiftKey && document.activeElement === last ) {
			e.preventDefault();
			first.focus();
		}
	}

	/* ------------------------------- Bootstrap -------------------------------- */

	function init() {
		document.querySelectorAll( '.wohno-card:not([data-wohno-ready])' ).forEach( initCard );
	}

	if ( 'loading' === document.readyState ) {
		document.addEventListener( 'DOMContentLoaded', init );
	} else {
		init();
	}

	// Re-init cards added by "load more".
	document.addEventListener( 'wohno:listings-appended', init );
} )();
