/**
 * Kurato Pipeline-Board (Etappe K3).
 *
 * No-Build-React (globale wp.*-Objekte, D13/D14). Zeigt die Stufen als Spalten
 * und die Kontakte als Karten. Verschoben wird ueber ein Auswahlfeld je Karte
 * (tastaturbedient, barrierefrei, UX-KONZEPT 7), nicht per Drag-and-drop.
 * Spricht kurato/v1/pipeline und den Stage-Move-Endpunkt.
 */
( function ( wp ) {
	'use strict';

	var el = wp.element.createElement;
	var useState = wp.element.useState;
	var useEffect = wp.element.useEffect;
	var render = wp.element.render;
	var cfg = window.kuratoBoard || {};
	var i18n = cfg.i18n || {};

	function t( key, fallback ) {
		return i18n[ key ] || fallback;
	}

	/**
	 * REST-Aufruf mit Nonce.
	 *
	 * @param {string} path   Pfad relativ zu restBase.
	 * @param {Object} [opts] fetch-Optionen.
	 * @return {Promise<Object>}
	 */
	function api( path, opts ) {
		opts = opts || {};
		opts.headers = opts.headers || {};
		opts.headers[ 'X-WP-Nonce' ] = cfg.nonce;
		opts.headers[ 'Content-Type' ] = 'application/json';
		opts.credentials = 'same-origin';
		return fetch( cfg.restBase + path, opts ).then( function ( res ) {
			return res.json().then( function ( body ) {
				if ( ! res.ok ) {
					throw new Error( ( body && body.message ) || 'Fehler' );
				}
				return body;
			} );
		} );
	}

	function Card( props ) {
		var contact = props.contact;
		var stages = props.stages;

		var name = el(
			'a',
			{
				className: 'hs-card-name',
				href: cfg.contactBaseUrl + '&contact=' + contact.id,
			},
			contact.name || contact.email || ( t( 'contact', 'Kontakt' ) + ' #' + contact.id )
		);

		var children = [ name ];
		if ( contact.email && contact.name ) {
			children.push( el( 'span', { key: 'mail', className: 'hs-card-email' }, contact.email ) );
		}

		if ( cfg.canManage ) {
			children.push(
				el(
					'select',
					{
						key: 'move',
						className: 'hs-card-move',
						value: String( props.stageId ),
						'aria-label': t( 'moveTo', 'Verschieben nach' ),
						onChange: function ( e ) {
							props.onMove( contact.id, props.stageId, parseInt( e.target.value, 10 ) );
						},
					},
					stages.map( function ( s ) {
						return el( 'option', { key: s.id, value: String( s.id ) }, s.label );
					} )
				)
			);
		}

		return el( 'li', { className: 'hs-card' }, children );
	}

	function Column( props ) {
		var stage = props.stage;
		return el(
			'div',
			{ className: 'hs-column' + ( stage.is_won ? ' is-won' : stage.is_lost ? ' is-lost' : '' ) },
			el(
				'div',
				{ className: 'hs-column-head' },
				el( 'span', { className: 'hs-column-title' }, stage.label ),
				el( 'span', { className: 'hs-column-count' }, stage.count )
			),
			el(
				'ul',
				{ className: 'hs-column-cards' },
				stage.contacts.length === 0
					? el( 'li', { className: 'hs-column-empty' }, t( 'columnEmpty', 'Keine Kontakte' ) )
					: stage.contacts.map( function ( c ) {
							return el( Card, {
								key: c.id,
								contact: c,
								stageId: stage.id,
								stages: props.stages,
								onMove: props.onMove,
							} );
					  } )
			)
		);
	}

	function App() {
		var boardState = useState( null );
		var board = boardState[ 0 ];
		var setBoard = boardState[ 1 ];
		var errorState = useState( '' );

		useEffect( function () {
			api( '/pipeline' )
				.then( function ( data ) {
					setBoard( Array.isArray( data ) ? data : [] );
				} )
				.catch( function ( err ) {
					errorState[ 1 ]( err.message );
				} );
		}, [] );

		function moveContact( contactId, fromStageId, toStageId ) {
			if ( fromStageId === toStageId ) {
				return;
			}
			// Optimistisch lokal verschieben, dann per REST bestaetigen.
			var moved = null;
			var next = board.map( function ( stage ) {
				var copy = Object.assign( {}, stage );
				copy.contacts = stage.contacts.filter( function ( c ) {
					if ( c.id === contactId && stage.id === fromStageId ) {
						moved = c;
						return false;
					}
					return true;
				} );
				return copy;
			} );
			if ( moved ) {
				next = next.map( function ( stage ) {
					if ( stage.id === toStageId ) {
						var copy = Object.assign( {}, stage );
						copy.contacts = [ moved ].concat( stage.contacts );
						copy.count = ( stage.count || 0 ) + 1;
						return copy;
					}
					if ( stage.id === fromStageId ) {
						var c2 = Object.assign( {}, stage );
						c2.count = Math.max( 0, ( stage.count || 0 ) - 1 );
						return c2;
					}
					return stage;
				} );
				setBoard( next );
			}

			api( '/contacts/' + contactId + '/stage', {
				method: 'POST',
				body: JSON.stringify( { stage_id: toStageId } ),
			} ).catch( function () {
				// Bei Fehler das Board neu laden, um konsistent zu bleiben.
				api( '/pipeline' ).then( function ( data ) {
					setBoard( Array.isArray( data ) ? data : [] );
				} );
				window.alert( t( 'moveError', 'Der Kontakt konnte nicht verschoben werden.' ) );
			} );
		}

		if ( errorState[ 0 ] ) {
			return el( 'p', { className: 'hs-board-error' }, errorState[ 0 ] );
		}
		if ( null === board ) {
			return el( 'p', { className: 'hs-board-loading' }, t( 'loading', 'Wird geladen.' ) );
		}

		var stages = board.map( function ( s ) {
			return { id: s.id, label: s.label };
		} );

		return el(
			'div',
			{ className: 'hs-board' },
			board.map( function ( stage ) {
				return el( Column, {
					key: stage.id,
					stage: stage,
					stages: stages,
					onMove: moveContact,
				} );
			} )
		);
	}

	document.addEventListener( 'DOMContentLoaded', function () {
		var mount = document.getElementById( 'hs-kurato-board' );
		if ( mount ) {
			render( el( App ), mount );
		}
	} );
} )( window.wp );
