<?php

namespace Drupal\basket\Admin\Page;

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

class PaymentPage{
	protected static $Basket;

	public function __construct(){
		self::$Basket = \Drupal::service('Basket');
	}
	public function table(){
		$elements = [
			[
                '#prefix'       => '<div class="basket_table_wrap">',
                '#suffix'       => '</div>',
                [
                    '#prefix'       => '<div class="b_content">',
                    '#suffix'       => '</div>',
                    [
                        \Drupal::formBuilder()->getForm(new PaymentListSettingsForm())
                    ]
                ],
            ],
            'CreateLink'	=> [
            	'#type'         => 'inline_template',
                '#template'     => '<a href="javascript:void(0);" onclick="{{onclick}}" data-post="{{post}}" id="CreateLink">+ {{text}}</a>',
                '#context'      => [
                    'text'          => self::$Basket->Translate()->t('Create'),
                    'onclick'       => 'basket_admin_ajax_link(this, \''.Url::fromRoute('basket.admin.pages', ['page_type' => 'api-create_payment'])->toString().'\')',
                    'post'          => json_encode([
                         'type'          => 'payment'
                     ])
                ],
            ]
		];
        $elements[] = \Drupal\basket\Admin\Page\Blocks::payments();
        return $elements;
	}
	public function ApiResponseAlter(&$response, $pageSubtype = NULL){
		switch($pageSubtype){
			case'create_payment':
            case'edit_payment':
				$tid = !empty($_POST['tid']) ? $_POST['tid'] : NULL;
				\Drupal::service('BasketPopup')->openModal(
                    $response,
                    self::$Basket->Translate()->t('Create'), 
                    \Drupal::formBuilder()->getForm(new PaymentSettingsForm($tid)),
                    [
                        'width' => 960,
                        'class' => []
                    ]
                );
			break;
		}
	}
}
/*
 PaymentListSettingsForm
*/
class PaymentListSettingsForm extends FormBase{
	protected static $Basket;
    protected static $Services;
    protected static $ServicesSettings;

    function __construct(){
        self::$Basket = \Drupal::service('Basket');
        self::$Services = \Drupal::service('BasketPayment')->getDefinitions();
        self::$ServicesSettings = self::$Basket->getSettings('payment_services', NULL);
    }
    public function getFormId(){
        return 'basket_payment_list_settings_form';
    }
    public function buildForm(array $form, FormStateInterface $form_state){
    	$form += [
            '#prefix'       => '<div id="basket_payment_list_settings_form">',
            '#suffix'       => '</div>'
        ];
        $form['payment_enabled'] = [
            '#type'         => 'checkbox',
            '#title'        => self::$Basket->Translate()->t('Enable service'),
            '#default_value'=> self::$Basket->getSettings('enabled_services', 'payment')
        ];
        $form['payment_default'] = [
            '#type'             => 'radio',
            '#title'            => self::$Basket->Translate()->t('The default is empty'),
            '#attributes'       => [
                'checked'			=> self::$Basket->getSettings('active_services', 'payment_default.0')
            ],			
            '#parents'      	=> ['active_default'],
            '#return_value'     => 0,
        ];
        $form['config_wrap'] = [
        	'#type'         => 'container',
            '#states'       => [
                'visible'       => [
                    'input[name="payment_enabled"]' => ['checked' => TRUE]
                ]
            ],
            'config'        => [
            	'#type'         => 'table',
            	'#header'       => [
                    '',
                    self::$Basket->Translate()->t('Active'),
                    self::$Basket->Translate()->t('Name'),
                    self::$Basket->Translate()->t('Default'),
                    self::$Basket->Translate()->t('Service'),
                    self::$Basket->Translate()->t('Settings'),
                    '',
                    '',
                ],
                '#tabledrag'    => [
                    [
                        'action'        => 'order',
                        'relationship'  => 'sibling',
                        'group'         => 'group-order-weight',
                    ]
                ],
                '#empty'        => self::$Basket->Translate()->t('The list is empty.')
            ]
        ];
        if(!empty($results = \Drupal::service('Basket')->Term()->tree('payment'))){
            foreach ($results as $result){
                $form['config_wrap']['config'][$result->id] = [
                    '#attributes'       => [
                        'class'             => ['draggable']
                    ],
                    '#weight'           => $result->weight,
                    'handle'            => [
                        '#wrapper_attributes'=> [
                            'class'     => ['tabledrag-handle-td']
                        ]
                    ],
                    'active'            => [
                        '#type'             => 'checkbox',
                        '#title'            => 'ON',
                        '#attributes'       => [
                            'class'             => ['not_label']
                        ],
                        '#parents'      	=> ['active_config', $result->id],
                        '#default_value'	=> self::$Basket->getSettings('active_services', 'payment.'.$result->id)
                    ],
                    'id'                => [
                        '#type'             => 'item',
                        '#markup'           => self::$Basket->Translate()->t(trim($result->name)),
                        '#value'            => $result->id,
                        '#field_suffix'     => self::$Basket->Translate()->getTranslateLink(trim($result->name))
                    ],
                    'default'            => [
                        '#type'             => 'radio',
                        '#title'            => 'ON',
                        '#attributes'       => [
                            'class'             => ['not_label'],
                            'checked'			=> self::$Basket->getSettings('active_services', 'payment_default.'.$result->id)
                        ],			
                        '#parents'      	=> ['active_default'],
                        '#return_value'     => $result->id,
                    ],
                    'service'           => [
                        '#type'             => 'inline_template',
                        '#template'         => '{% if id %}<b>{{ basket_t(name, {}, provider) }}</b>{% endif %}',
                        '#context'          => !empty(self::$ServicesSettings[$result->id]) && !empty(self::$Services[self::$ServicesSettings[$result->id]]) ? self::$Services[self::$ServicesSettings[$result->id]] : []
                    ],
                    'settings'          => self::getSettingsInfo($result),
                    'weight'            => [
                        '#type'             => 'number',
                        '#attributes'       => [
                            'class'             => ['group-order-weight']
                        ],
                        '#default_value'    => $result->weight
                    ],
                    'links'             => [
                        '#type'             => 'inline_template',
                        '#template'         => '<a href="javascript:void(0);" class="settings_row tooltipster_init">{{ico|raw}}</a>
                            <div class="tooltipster_content">
                                <a href="javascript:void(0);" class="button--link" onclick="{{link[0].onclick}}" data-post="{{link[0].post}}"><span class="ico">{{ link[0].ico|raw }}</span> {{ link[0].text }}</a><br/>
                                <a href="javascript:void(0);" class="button--link" onclick="{{link[1].onclick}}" data-post="{{link[1].post}}"><span class="ico">{{ link[1].ico|raw }}</span> {{ link[1].text }}</a>
                            </div>',
                        '#context'          => [
                            'ico'               => self::$Basket->getIco('settings_row.svg', 'base'),
                            'link'              => [
                                [
                                    'text'          => self::$Basket->Translate()->t('Edit'),
                                    'ico'           => self::$Basket->getIco('edit.svg'),
                                    'onclick'       => 'basket_admin_ajax_link(this, \''.Url::fromRoute('basket.admin.pages', ['page_type' => 'api-edit_payment'])->toString().'\')',
                                    'post'          => json_encode([
                                        'type'          => $result->type,
                                        'tid'           => $result->id
                                    ])
                                ],[
                                    'text'          => self::$Basket->Translate()->t('Delete'),
                                    'ico'           => self::$Basket->getIco('trash.svg'),
                                    'onclick'       => 'basket_admin_ajax_link(this, \''.Url::fromRoute('basket.admin.pages', ['page_type' => 'api-delete_term'])->toString().'\')',
                                    'post'          => json_encode([
                                        'delete_tid'    => $result->id
                                    ])
                                ]
                            ]
                        ],
                        '#wrapper_attributes'=> [
                            'class'             => ['td_settings_row']
                        ]
                    ]
                ];
            }
        }
        $form['payment_widget'] = [
            '#type'         => 'select',
            '#title'        => t('Widget'),
            '#options'      => [
                'select'        => t('Select list'),
                'radios'        => t('Radios')
            ],
            '#default_value'=> self::$Basket->getSettings('enabled_services', 'payment_widget'),
            '#states'       => [
                'visible'       => [
                    'input[name="payment_enabled"]' => ['checked' => TRUE]
                ]
            ],
        ];
        $form['actions'] = [
            '#type'         => 'actions',
            'submit'        => [
                '#type'         => 'submit',
                '#value'        => self::$Basket->Translate()->t('Save'),
                '#ajax'         => [
                    'wrapper'       => 'basket_payment_list_settings_form',
                    'callback'      => '::ajaxSubmit'
                ]
            ]
        ];
        return $form;
    }
    public function submitForm(array &$form, FormStateInterface $form_state){
    	// enabled_services
        self::$Basket->setSettings(
            'enabled_services', 
            'payment', 
            $form_state->getValue('payment_enabled')
        );
        self::$Basket->setSettings(
            'enabled_services', 
            'payment_widget', 
            $form_state->getValue('payment_widget')
        );
        // Set active settings
        self::$Basket->setSettings(
            'active_services', 
            'payment', 
            $form_state->getValue('active_config')
        );
        // Set active default
        self::$Basket->setSettings(
            'active_services', 
            'payment_default', 
            [$form_state->getValue('active_default') => TRUE]
        );
        // weight
        foreach ($form_state->getValue('config') as $row){
                \Drupal::database()->update('basket_terms')
                            ->fields([
                                'weight'    => $row['weight']
                            ])
                            ->condition('id', $row['id'])
                            ->execute();
        }
    }
    public static function ajaxSubmit(array &$form, FormStateInterface $form_state){
        $response = new AjaxResponse();
        $response->addCommand(new InvokeCommand('.messages, .tabledrag-changed', 'remove', []));
        $response->addCommand(new InvokeCommand('.drag-previous', 'removeClass', ['drag-previous']));
        $response->addCommand(new InvokeCommand(NULL, 'NotyGenerate', ['status', \Drupal::service('Basket')->Translate()->t('Settings saved.')]));
        return $response;
    }
    private static function getSettingsInfo($result){
        $items = [];
        if(!empty(self::$ServicesSettings[$result->id]) && !empty($system = self::$Services[self::$ServicesSettings[$result->id]])){
            $items = \Drupal::service('BasketPayment')->getSettingsInfoList($result->id, $system);
            if(!empty($system['provider'])){
                $module_info = \Drupal::service('extension.list.module')->getExtensionInfo($system['provider']);
                if(!empty($module_info['configure'])){
                    $items[] = [
                        '#type'         => 'inline_template',
                        '#template'     => '<a href="{{ url }}" target="_blank" class="button--link target">{{ text }}</a>',
                        '#context'      => [
                            'text'          => self::$Basket->Translate()->t('Settings page'),
                            'url'           => Url::fromRoute($module_info['configure'])->toString()
                        ]
                    ];
                }
            }
        }
        /*Connection with the delivery*/
        $deliveryItems = [];
        if(!empty($deliveryReference = self::$Basket->getSettings('payment_delivery_reference', $result->id))){
            $deliveryOptions = \Drupal::service('Basket')->Term()->getOptions('delivery');
            foreach ($deliveryReference as $tid){
                if(empty($deliveryOptions[$tid])) continue;
                $deliveryItems[] = $deliveryOptions[$tid];
            }
        }
        if(empty($deliveryItems)){
            $deliveryItems[] = self::$Basket->Translate()->t('For all deliveries');
        }
        if(!empty($deliveryItems)){
            $items[] = [
                '#type'         => 'inline_template',
                '#template'     => '<b>{{ label }}:</b><br/>- {{ items|join(\'\n - \')|nl2br }}',
                '#context'      => [
                    'label'         => self::$Basket->Translate()->t('Available on delivery'),
                    'items'         => $deliveryItems
                ]
            ];
        }
        /*Description*/
        if(!empty($result->description)){
            $items[] = [
                '#type'         => 'inline_template',
                '#template'     => '<b>{{ label }}:</b><br/>- {{ description|nl2br }} {{ trans }}',
                '#context'      => [
                    'label'         => self::$Basket->Translate()->t('Description'),
                    'description'   => self::$Basket->Translate()->t(trim($result->description)),
                    'trans'         => self::$Basket->Translate()->getTranslateLink(trim($result->description))
                ],
            ];
        }
        /**/
        return [
            '#theme'            => 'item_list',
            '#list_type'        => 'ul',
            '#wrapper_attributes'=> [
                'class'             => ['settings_list_block']
            ],
            '#items'            => $items
        ];
    }
}
/*
 PaymentSettingsForm
*/
class PaymentSettingsForm extends FormBase{
	protected static $Basket;
    protected static $term;
    protected static $TermServiceDef;

    function __construct($editTid = NULL){
        self::$Basket = \Drupal::service('Basket');
        self::$term = !empty($editTid) ? \Drupal::service('Basket')->Term()->load($editTid) : NULL;
        if(!empty(self::$term->id)){
            self::$TermServiceDef = self::$Basket->getSettings('payment_services', self::$term->id);
        }
    }
    public function getFormId(){
        return 'basket_payment_settings_form';
    }
    public function buildForm(array $form, FormStateInterface $form_state){
    	$form += [
            '#prefix'       => '<div id="basket_payment_settings_form_ajax_wrap">',
            '#suffix'       => '</div>',
            'status_messages'=> [
                '#type'         => 'status_messages'
            ]
        ];
        $form['tid'] = [
            '#type'         => 'hidden',
            '#value'        => !empty(self::$term->id) ? self::$term->id : NULL
        ];
        $form['name'] = [
            '#type'         => 'textfield',
            '#title'        => self::$Basket->Translate()->t('Name').' EN',
            '#required'     => TRUE,
            '#default_value'=> !empty(self::$term->name) ? self::$term->name : ''
        ];
        $form['description'] = [
            '#type'         => 'textarea',
            '#title'        => self::$Basket->Translate()->t('Description').' EN',
            '#rows'         => 2,
            '#default_value'=> !empty(self::$term->description) ? self::$term->description : ''
        ];
        $services = [];
        if(!empty($payments = \Drupal::service('BasketPayment')->getDefinitions())){
            foreach ($payments as $payment){
                $services[$payment['id']] = self::$Basket->Translate(trim($payment['provider']))->t(trim($payment['name']));
            }
        }
        $form['service'] = [
            '#type'         => 'select',
            '#title'        => self::$Basket->Translate()->t('Service'),
            '#options'      => $services,
            '#empty_option' => self::$Basket->Translate()->t('Not specified'),
            '#default_value'=> self::$TermServiceDef,
        ];
        $form['#submit'][] = [$this, 'submitFormSave'];
        /*Service alter*/
        \Drupal::service('BasketPayment')->paymentSettingsFormAlter($form, $form_state);
        /*Connection with the delivery*/
        $this->deliveryPaymentOptions($form, $form_state);
        /*---*/
        $form['actions'] = [
            '#type'         => 'actions',
            'submit'        => [
                '#type'         => 'submit',
                '#value'        => self::$Basket->Translate()->t('Save'),
                '#ajax'         => [
                    'wrapper'       => 'basket_payment_settings_form_ajax_wrap',
                    'callback'      => '::ajaxSubmit'
                ]
            ]
        ];
    	return $form;
    }
    public function submitForm(array &$form, FormStateInterface $form_state){}
    public function submitFormSave(array &$form, FormStateInterface $form_state){
        $values = $form_state->getValues();
        if(!empty($values['tid'])){
            \Drupal::database()->update('basket_terms')
                        ->fields([
                            'name'          => trim($values['name']),
                            'description'   => trim($values['description']),
                        ])
                        ->condition('id', $values['tid'])
                        ->execute();
        } else {
            $values['tid'] = \Drupal::database()->insert('basket_terms')
                        ->fields([
                            'type'          => 'payment',
                            'name'          => trim($values['name']),
                            'description'   => trim($values['description']),
                            'weight'        => -100
                        ])
                        ->execute();
        }
        /*Update service info*/
        self::$Basket->setSettings(
            'payment_services', 
            $values['tid'], 
            $form_state->getValue('service')
        );
        $form_state->setValue('tid', $values['tid']);
        /*Connection with the delivery*/
        $deliverys = $form_state->getValue('delivery');
        if(!empty($deliverys)){
            foreach ($deliverys as $key => $value) {
                if(empty($value)) unset($deliverys[$key]);
            }
        }
        self::$Basket->setSettings(
            'payment_delivery_reference',
            $values['tid'],
            $deliverys 
        );
    }
    public static function ajaxSubmit(array &$form, FormStateInterface $form_state){
        if ($form_state->isSubmitted() && $form_state->getErrors()) {
            return $form;
        } else {
            $response = new AjaxResponse();
            $response->addCommand(new InvokeCommand('body', 'append', ['<script>location.reload();</script>']));
            $response->addCommand(new InvokeCommand(NULL, 'NotyGenerate', ['status', \Drupal::service('Basket')->Translate()->t('Settings saved.')]));
            return $response;
        }
    }
    public function deliveryPaymentOptions(&$form, &$form_state){
        $form['delivery'] = [
            '#type'         => 'checkboxes',
            '#title'        => self::$Basket->Translate()->t('Available on delivery'),
            '#options'      => \Drupal::service('Basket')->Term()->getOptions('delivery'),
            '#description'  => self::$Basket->Translate()->t('If not specified, it will be available to anyone'),
            '#default_value'=> !empty(self::$term->id) ? self::$Basket->getSettings('payment_delivery_reference', self::$term->id) : NULL
        ];
    }
}