<?php

namespace Drupal\basket;

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\HtmlCommand;
use Drupal\Core\Ajax\RedirectCommand;
use Drupal\Core\Ajax\InvokeCommand;
use Drupal\Core\Url;

class BasketOrderForm{

	protected static $Basket;
	protected static $phoneMaskSettings;

	function __construct(){
		self::$Basket = \Drupal::service('Basket');
		self::$phoneMaskSettings = self::$Basket->getSettings('order_form', 'config.phone_mask');
	}
	public static function formAlter(&$form, &$form_state){
		$form['status_messages'] = [
			'#type'				=> 'status_messages'
		];
		$entity = $form_state->getBuildInfo()['callback_object']->getEntity();
		// Extra fields
		\Drupal::service('BasketDelivery')->extraFieldFormAlter($form, $form_state, $entity);
		\Drupal::service('BasketPayment')->extraFieldFormAlter($form, $form_state, $entity);
		// Form ajax
		$form['#prefix'] = '<div id="basket_node_basket_order_form_ajax_wrap">';
        $form['#suffix'] = '</div>';
		hide($form['status']);
		hide($form['advanced']);
		if(!empty($form['title'])) $form['title']['#access'] = FALSE;
		if(!empty($entity->basket_admin_process)){
			$Order = new \Drupal\basket\Admin\Page\Order($entity->basket_admin_process->id);
			$Order->nodeFormAlter($form, $form_state);
		} else {
			// Form submit
			if(empty($entity->id()) && !empty($submitButtonText = self::$Basket->getSettings('order_form', 'config.submit_button'))){
				$form['actions']['submit']['#value'] = self::$Basket->Translate()->t(trim($submitButtonText));
			}
	        $form['actions']['submit']['#ajax'] = array(
	            'wrapper'       => 'basket_node_basket_order_form_ajax_wrap',
	            'callback'      => '\\'.__CLASS__.'::submitAjax',
	            'event'         => 'click',
	            'progress'      => ['type' => 'fullscreen']
	        );
	        if(empty($entity->id())){
	            $form['actions']['submit']['#submit']['basketInsert'] =  '\\'.__CLASS__.'::insertSubmit';
	        }
	        if(!\Drupal::currentUser()->hasPermission('basket order_access')){
	        	$form['#validate']['empty_validate'] = __CLASS__.'::emptyOrderValidate';
	        }
		}
		// Phone mask
		if(!empty(self::$phoneMaskSettings['field']) && !empty($form[self::$phoneMaskSettings['field']]['widget'][0]['value'])){
			$form['#attached']['library'][] = 'basket/jquery.inputmask';
			$form[self::$phoneMaskSettings['field']]['widget'][0]['value']['#attributes']['class'][] = 'js-basket-input-mask';
			$form[self::$phoneMaskSettings['field']]['widget'][0]['value']['#attributes']['data-inputmask'] = '\'mask\': \''.trim(self::$phoneMaskSettings['mask']).'\'';
		}
	}
	public static function submitAjax($form, $form_state){
		$response = new AjaxResponse();
		if ($form_state->hasAnyErrors()){
		    unset($form['#prefix'], $form['#suffix']);
		    $response->addCommand(new HtmlCommand('#'.$form['actions']['submit']['#ajax']['wrapper'], $form));
		} else {
			$entity = $form_state->getBuildInfo()['callback_object']->getEntity();
			if(!empty($entity->basket_admin_process)){
				// Admin order edit/create
				\Drupal::messenger()->deleteAll();
				$response->addCommand(new InvokeCommand(NULL, 'NotyGenerate', ['status', self::$Basket->Translate()->t('Settings saved.')]));
				// Return form
				unset($form['#prefix'], $form['#suffix']);
		    	$response->addCommand(new HtmlCommand('#'.$form['actions']['submit']['#ajax']['wrapper'], $form));
		    	$response->addCommand(new InvokeCommand('input[name="changed"]', 'val', [$entity->get('changed')->value]));
			} else {
				$_SESSION['basket_finish_nid'] = $entity->id();
				// Redirect
				$redirect = \Drupal::service('Basket')->getSettings('order_form', 'config.submit_redirect');
				// Payment redirect
				$getPaymentInfo = \Drupal::service('BasketPayment')->getPayInfo($entity);
				$paySystem = $payId = NULL;
				if(!empty($getPaymentInfo->payInfo)){
					$redirect = 'payment';
					list($paySystem, $payId) = explode('|', $getPaymentInfo->payInfo);
					if(!empty($getPaymentInfo->payUrl)){
						$redirect = $getPaymentInfo->payUrl;
					}
				}
				// ---
				switch($redirect){
					case'<front>':
						$response->addCommand(
							new RedirectCommand(
								Url::fromRoute('<front>')->toString()
							)
						);
					break;
					case'finish':
						 $response->addCommand(
						 	new RedirectCommand(
						 		Url::fromRoute('basket.pages', [
						 			'page_type' 	=> 'finish'
						 		])->toString()
						 	)
						 );
					break;
					case'reload':
						$response->addCommand(
							new InvokeCommand('body', 'append', ['<script>location.reload();</script>'])
						);
					break;
					case'payment':
						$response->addCommand(
						 	new RedirectCommand(Url::fromRoute('basket.pages', [
						 		'page_type' 		=> 'payment'
						 	],[
						 		'query'				=> [
						 			'payInfo'			=> base64_encode(serialize([
						 				'paySystem'			=> $paySystem,
						 				'payId'				=> $payId
						 			]))
						 		]
						 	])->toString())
						);
					break;
					default:
						$response->addCommand(
							new RedirectCommand($redirect)
						);
					break;
				}
				// Message
				\Drupal::messenger()->deleteAll();
				if(!empty($message = \Drupal::service('Basket')->getSettings('order_form', 'config.submit_message'))){
					\Drupal::messenger()->addMessage(\Drupal::service('Basket')->Translate()->t(trim($message)), 'status');
				}
			}
		}
		return $response;
	}
	public static function insertSubmit($form, \Drupal\Core\Form\FormStateInterface $form_state){
        $entity = $form_state->getBuildInfo()['callback_object']->getEntity();
        \Drupal\basket\Entity::insertOrder($entity, $form_state);
    }
	public static function emptyOrderValidate($form, \Drupal\Core\Form\FormStateInterface $form_state){
		$Basket = \Drupal::service('Basket');
        $count = $Basket->Cart()->getCount();
        if(empty($count)){
	        $form_state->setErrorByName('orderCount', $Basket->Translate()->t('You have added 0 items to cart!'));
        }
    }
}