<?php
namespace Drupal\basket\Admin\Page;

use Drupal\Core\Url;

class Templates{

	protected static $Basket;
    protected static $getTemplateYamls;

	public static function page($activeTemplate = NULL){
        return [
			'orders'		=> [
				'#prefix'		=> '<div class="basket_table_wrap">',
				'#suffix'		=> '</div>',
				'title'			=> [
					'#prefix'		=> '<div class="b_title">',
					'#suffix'		=> '</div>',
					'#markup'		=> \Drupal::service('Basket')->Translate()->t('Templates')
				],
				'content'		=> [
					'#prefix'		=> '<div class="b_content">',
					'#suffix'		=> '</div>',
					self::getTemplates($activeTemplate)
				]
			]
		];
	}
    public static function preview($activeTemplate = NULL){
        $MailCenter = \Drupal::service('Basket')->MailCenter();
        print $MailCenter->getHtml([
            'template'      => $activeTemplate
        ]);
        exit;
    }
	private static function getTemplates($activeTemplate){
		if(!self::$Basket){
			self::$Basket = \Drupal::service('Basket');
		}
		$templates = [];
		$ymldata = self::getTemplateYamls();
		if(!empty($ymldata)){
			foreach ($ymldata as $groupKey => $groupInfo){
                $templates[$groupKey] = [
                    '#type'         => 'details',
                    '#title'        => self::$Basket->Translate()->t($groupInfo['title'])
                ];
                if(!empty($groupInfo['templates'])){
                    foreach ($groupInfo['templates'] as $templateKey => $templateInfo){
                        $class = ['template_item'];
                        if($activeTemplate == $templateKey){
                            $class[] = 'is-active';
                            $templates[$groupKey]['#open'] = TRUE;
                        }
                        $title_context = !empty($templateInfo['title_context']) ? $templateInfo['title_context'] : 'basket';
                        $templates[$groupKey][$templateKey] = [
                            '#prefix'       => '<div class="'.implode(' ', $class).'">',
                            '#suffix'       => '</div>',
                            [
                                '#type'         => 'link',
                                '#title'        => self::$Basket->Translate($title_context)->t(trim($templateInfo['title'])),
                                '#url'          => new Url('basket.admin.pages', [
                                    'page_type'     => 'settings-templates-'.$templateKey
                                ]),
                                '#prefix'       => '<div class="link_wrap">',
                                '#suffix'       => '</div>'
                            ]
                        ];
                        if($activeTemplate == $templateKey){
                            $templateInfo['id'] = $templateKey;
                            $templates[$groupKey][$templateKey][] = \Drupal::formBuilder()->getForm(new TemplateSettingsForm($templateInfo));
                        }
                    }
                }
			}
		}
		return $templates;
	}
    public static function getTemplateYamls(){
        if(!self::$getTemplateYamls){
            $ymldata = [];
            $templates_file = drupal_get_path('module', 'basket').'/config/basket_install/Templates.yml';
            if(file_exists($templates_file)){
                $ymldata = \Drupal\Component\Serialization\Yaml::decode(file_get_contents($templates_file));
                // subModules
                $subModules = [];
                \Drupal::moduleHandler()->alter('basket_translate_context', $subModules);
                if(!empty($subModules)){
                    foreach ($subModules as $subModule){
                        $templatesSubFile = drupal_get_path('module', $subModule).'/config/basket_install/Templates.yml';
                        if(file_exists($templatesSubFile)){
                            $ymlSubData = \Drupal\Component\Serialization\Yaml::decode(file_get_contents($templatesSubFile));
                            if(!empty($ymlSubData)){
                                $ymldata = \Drupal::service('Basket')->arrayMergeRecursive($ymldata, $ymlSubData);
                            }
                        }
                    }
                }
            }
            self::$getTemplateYamls = $ymldata;
        }
        return self::$getTemplateYamls;
    }
}

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\InvokeCommand;

class TemplateSettingsForm extends FormBase{
	protected static $Basket;
	protected static $templateInfo;
    public function __construct($templateInfo){
    	self::$templateInfo = $templateInfo;
        self::$Basket = \Drupal::service('Basket');
    }
    public function getFormId(){
        return 'basket_template_settings_form';
    }
    public function buildForm(array $form, FormStateInterface $form_state){
    	$values = $form_state->getValues();
    	$form['status_messages'] = [
    		'#type'			=> 'status_messages'
    	];
    	$form['#prefix'] = '<div id="basket_template_settings_form_ajax_wrap">';
    	$form['#suffix'] = '</div>';
    	$form['config'] = [
    		'#tree'			=> TRUE
    	];
        $langPrefix = '';
    	if(!empty(self::$templateInfo['language'])){
    		$languages = \Drupal::languageManager()->getLanguages();
    		if(count($languages) > 1){
    			$options = [];
    			foreach ($languages as $language){
    				$options[$language->getId()] = $language->getName();
    			}
	    		$form['config']['language'] = [
	    			'#type'			=> 'radios',
	    			'#options'		=> $options,
	    			'#default_value'=> \Drupal::languageManager()->getCurrentLanguage()->getId(),
	    			'#ajax'			=> [
	    				'wrapper'		=> 'basket_template_settings_form_ajax_wrap',
	    				'callback'		=> '::ajaxCallback'
	    			],
	    			'#prefix'		=> '<div class="language_switch">',
	    			'#suffix'		=> '</div>'
	    		];
    		}
    		$langPrefix = '_'.\Drupal::languageManager()->getCurrentLanguage()->getId();
    		if(!empty($values['config']['language'])){
    			$langPrefix = '_'.$values['config']['language'];
    		}
    	}
    	// ---
    	$config = \Drupal::service('Basket')->getSettings('templates', self::$templateInfo['id'].$langPrefix);
        if(!empty(self::$templateInfo['subject'])){
            $form['config']['subject'.$langPrefix] = [
            '#type'         => 'textfield',
            '#title'        => self::$Basket->Translate()->t('Subject'),
            '#default_value'=> !empty($config['config']['subject']) ? $config['config']['subject'] : NULL
        ];
        }
    	// ---
    	$form['config']['template'.$langPrefix] = [
    		'#type'			=> 'textarea',
    		'#title'		=> self::$Basket->Translate()->t('Template'),
    		'#rows'			=> 15,
    		'#default_value'=> !empty($config['config']['template']) ? $config['config']['template'] : NULL
    	];
    	if(!empty(self::$templateInfo['text_format'])){
    		$form['config']['template'.$langPrefix]['#type'] = 'text_format';
    		$form['config']['template'.$langPrefix]['#default_value'] = !empty($config['config']['template']['value']) ? $config['config']['template']['value'] : NULL;
    		$form['config']['template'.$langPrefix]['#format'] = !empty($config['config']['template']['format']) ? $config['config']['template']['format'] : NULL;
    	}
        if(!empty(self::$templateInfo['inline_twig'])){
            $form['config']['template'.$langPrefix]['#attributes']['class'][] = 'inline_twig';
            $form['#attached']['library'][] = 'basket/codemirror';
        }
        if(!empty(self::$templateInfo['token'])){
            self::templateToken($form);
        }
        self::templateTokenTwig($form);
    	if(!empty(self::$templateInfo['twig_template'])){
            self::templateTwigTemplate($form);
        }
    	$form['actions'] = [
    		'#type'			=> 'actions',
    		'submit'		=> [
    			'#type'			=> 'submit',
    			'#value'		=> t('Save configuration'),
                '#name'         => 'save',
    			'#ajax'			=> [
    				'wrapper'		=> 'basket_template_settings_form_ajax_wrap',
    				'callback'		=> '::ajaxCallback'
    			],
    		]
    	];
        if(!empty(self::$templateInfo['preview'])){
            $form['actions']['preview'] = [
                '#type'         => 'button',
                '#value'        => self::$Basket->Translate()->t('Preview'),
                '#attributes'   => [
                    'class'         => ['preview'],
                    'title'         => self::$Basket->Translate()->t('Check the pop-up blocker in the browser')
                ],
                '#name'         => 'preview',
                '#ajax'         => [
                    'wrapper'       => 'basket_template_settings_form_ajax_wrap',
                    'callback'      => '::ajaxCallback'
                ]
            ];
        }
    	return $form;
    }
    public function submitForm(array &$form, FormStateInterface $form_state){
        $triggerdElement = $form_state->getTriggeringElement();
        if(!empty($triggerdElement['#name']) && $triggerdElement['#name'] == 'save'){
            $langPrefix = '';
            $config = $form_state->getValue('config');
            if(!empty(self::$templateInfo['language'])){
                $langPrefix = '_'.\Drupal::languageManager()->getCurrentLanguage()->getId();
                if(!empty($config['language'])){
                    $langPrefix = '_'.$config['language'];
                }
            }
            $setSettings = [
                'template'      => !empty($config['template'.$langPrefix]) ? $config['template'.$langPrefix] : [],
            ];
            if(isset($config['subject'.$langPrefix])){
                $setSettings['subject'] = !empty($config['subject'.$langPrefix]) ? $config['subject'.$langPrefix] : '';
            }
            self::$Basket->setSettings('templates', self::$templateInfo['id'].$langPrefix, ['config' => $setSettings]);
            \Drupal::messenger()->addMessage(self::$Basket->Translate()->t('Settings saved.'), 'status');
        }
    }
    public function ajaxCallback(array &$form, FormStateInterface $form_state){
        $triggerdElement = $form_state->getTriggeringElement();
        if(!empty($triggerdElement['#name']) && $triggerdElement['#name'] == 'preview'){
            $response = new AjaxResponse();
            $config = $form_state->getValue('config');
            $languages = \Drupal::languageManager()->getLanguages();
            if(!empty($config['language']) && !empty($languages[$config['language']])){
                $language = $languages[$config['language']];
            } else {
                $language = $languages[\Drupal::languageManager()->getCurrentLanguage()->getId()];
            }
            $response->addCommand(new InvokeCommand(NULL, 'BasketOpenNewWindow', [
                Url::fromRoute('basket.admin.pages', ['page_type' => 'settings-templates_preview-'.self::$templateInfo['id']],['language' => $language])->toString(),
                 600,
                '100%'
            ]));
            return $response;
        }
    	return $form;
    }
    private static function templateToken(&$form){
        $form['token'] = [
            '#theme'        => 'token_tree_link',
            '#token_types'  => ['user', 'node'],
            '#text'         => self::$Basket->Translate()->t('[available tokens]')
        ];
    }
    private static function templateTokenTwig(&$form){
        $tokents = [];
        if(!empty(self::$templateInfo['token_twig_class'])){
            list($token_twig_class, $token_twig_class_function) = explode('::', self::$templateInfo['token_twig_class']);
            $class = new $token_twig_class;
            self::$templateInfo['token_twig'] += $class->{$token_twig_class_function}();
        }
        // Alter
        \Drupal::moduleHandler()->alter('basketTemplateTokens', self::$templateInfo['token_twig'], self::$templateInfo['id']);
        // ---
        if(!empty(self::$templateInfo['token_twig'])){
            $title_context = !empty(self::$templateInfo['title_context']) ? self::$templateInfo['title_context'] : 'basket';
            foreach (self::$templateInfo['token_twig'] as $keyToken => $label) {
                $tokents[] = '{{'.$keyToken.'}} - <b>'.self::$Basket->Translate($title_context)->t(trim($label)).'</b>';
            }
        }
        if(!empty($tokents)){
            $form['token_twig'] = [
                '#type'         => 'details',
                '#title'        => self::$Basket->Translate()->t('Twig tokens'),
                '#description'  => implode('<br/>', $tokents)
            ];
        }
    }
    private static function templateTwigTemplate(&$form){
        $form['twig_template'] = [
             '#type'         => 'item',
             '#title'        => 'Twig template:',
             '#markup'       => self::$templateInfo['twig_template']
         ];
    }
}