<?php
namespace SabaiApps\Directories\Component\Fieldset\FormField;

use SabaiApps\Directories\Component\Form;

class FieldsFormField extends Form\Field\AbstractField {

	public function formFieldInit( $name, array &$data, Form\Form $form ) {
		if ( ! isset( $form->settings['#pre_render'][ __CLASS__ ] ) ) {
			$form->settings['#pre_render'][ __CLASS__ ] = array( $this, 'preRenderCallback' );
		}
	}

	public function formFieldRender( array &$data, Form\Form $form ) {
		if ( $values = $form->getValue( $data['#name'] ) ) {
			if ( ! empty( $data['#wrap'] ) ) {
				foreach ( array_reverse( $data['#wrap'] ) as $wrap ) {
					$values = array( $wrap => $values );
				}
			}
		} else {
			$values = null;
		}

		if ( ! $fieldset_form = $this->_getFieldsetForm( $form, $data, true, $values ) ) {
			return;
		}

		$rendered = $this->_application->Entity_Form_renderDisplay(
			$values ? $this->_application->Form_Form_build( $fieldset_form, false, $values ) : $fieldset_form
		);

		$html                    = array( $rendered['html'], $rendered['form']->getHiddenHtml() );
		$form->settings['#js'][] = $rendered['form']->getJsHtml( false );
		if ( ! empty( $data['#fieldset_id'] ) ) {
			$html[] = sprintf(
				'<input type="hidden" name="%s" value="%d" />',
				empty( $data['#wrap'] ) ? '_fieldset_id' : $this->_application->Form_Form_fieldName( array_merge( $data['#wrap'], array( '_fieldset_id' ) ) ),
				$data['#fieldset_id']
			);
		}
		$this->_render( implode( PHP_EOL, $html ), $data, $form );
	}

	public function formFieldSubmit( &$value, array &$data, Form\Form $form ) {
		if ( ! empty( $value ) ) {
			// Wrap values
			if ( ! empty( $data['#wrap'] ) ) {
				foreach ( array_reverse( $data['#wrap'] ) as $wrap ) {
					$value = array( $wrap => $value );
				}
			}
		}

		if ( ! $fieldset_form = $this->_getFieldsetForm( $form, $data, true, $value ) ) {
			return;
		}

		if ( ( $form_storage = $this->_application->getComponent( 'Form' )->getFormStorage( $fieldset_form['#build_id'] ) )
			&& is_array( $form_storage )
		) {
			$fieldset_form['#initial_storage'] = $form_storage;
		}
		$fieldset_form = $this->_application->Form_Form_build( $fieldset_form );
		if ( ! $fieldset_form->submit( $value, true ) ) { // Force submission as the parent form has already passed the submission check.
			if ( $errors = $fieldset_form->getError() ) {
				$form->setError( array_shift( $errors ), $data );
			}
			return;
		}

		if ( $value = $fieldset_form->values ) {
			// Unwrap values
			if ( ! empty( $data['#wrap'] ) ) {
				foreach ( $data['#wrap'] as $wrap ) {
					$value = $value[ $wrap ];
				}
			}
		}
	}

	public function preRenderCallback( Form\Form $form ) {
		$this->_application->Form_Scripts( array( 'fieldset_fields' ) );
	}

	protected function _getFieldsetForm( Form\Form $parentForm, array &$data, $wrap = true, $values = null ) {
		if ( empty( $data['#bundle'] )
			|| ( ! $bundle = $this->_application->Entity_Bundle( $data['#bundle'] ) )
		) {
			return;
		}

		if ( ! empty( $data['#fieldset_id'] ) ) {
			$id = $data['#fieldset_id'];
			if ( ! is_numeric( $id )
				|| ( ! $fieldset_entity = $this->_application->Entity_Entity( 'fieldset', $id ) )
				|| $fieldset_entity->getBundleName() !== $bundle->name
			) {
				unset( $fieldset_entity, $data['#fieldset_id'] );
			}
		}
		$form                    = $this->_application->Entity_Form(
			isset( $fieldset_entity ) ? $fieldset_entity : $bundle,
			array(
				'pre_render_display'    => true,
				'wrap'                  => $wrap && ! empty( $data['#wrap'] ) ? $data['#wrap'] : array(),
				'token'                 => false,
				'horizontal'            => true,
				'values'                => $values,
				'values_check_build_id' => false, // need this since no build ID
				'is_admin'              => $this->_application->getPlatform()->isAdmin(),
			)
		);
		$form['#id']             = $parentForm->settings['#id'] . '-' . md5( $data['#name'] );
		$form['#parent_id']      = $parentForm->settings['#id'];
		$form['#method']         = $parentForm->settings['#method'];
		$form['#token']          = false;
		$form['#build_id']       = $parentForm->settings['#build_id'] . '_' . md5( $data['#name'] );
		$form['#enable_storage'] = true;

		return $form;
	}
}
