<?php

namespace Drupal\basket\Admin\Page;

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

class DeliveryPage{

	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 DeliveryListSettingsForm())
                    ]
                ]
            ],
            '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_delivery'])->toString().'\')',
                    'post'          => json_encode([
                         'type'          => 'delivery'
                     ])
                ],
            ]
        ];
        $elements[] = \Drupal\basket\Admin\Page\Blocks::deliverys();
        return $elements;
  	}
    public function ApiResponseAlter(&$response, $pageSubtype = NULL){
        switch($pageSubtype){
            case'create_delivery':
            case'edit_delivery':
                $tid = !empty($_POST['tid']) ? $_POST['tid'] : NULL;
                \Drupal::service('BasketPopup')->openModal(
                    $response,
                    self::$Basket->Translate()->t('Create'), 
                    \Drupal::formBuilder()->getForm(new DeliverySettingsForm($tid)),
                    [
                        'width' => 960,
                        'class' => []
                    ]
                );
            break;
        }
    }
}
/*
 DeliveryListSettingsForm
*/
class DeliveryListSettingsForm extends FormBase{

    protected static $Basket;
    protected static $Services;
    protected static $ServicesSettings;

    function __construct(){
        self::$Basket = \Drupal::service('Basket');
        self::$Services = \Drupal::service('BasketDelivery')->getDefinitions();
        self::$ServicesSettings = self::$Basket->getSettings('delivery_services', NULL);
    }
    public function getFormId(){
        return 'basket_delivery_list_settings_form';
    }
    public function buildForm(array $form, FormStateInterface $form_state){
        $form += [
            '#prefix'       => '<div id="basket_delivery_list_settings_form">',
            '#suffix'       => '</div>'
        ];
        $form['delivery_enabled'] = [
            '#type'         => 'checkbox',
            '#title'        => self::$Basket->Translate()->t('Enable service'),
            '#default_value'=> self::$Basket->getSettings('enabled_services', 'delivery')
        ];
        $form['delivery_default'] = [
            '#type'             => 'radio',
            '#title'            => self::$Basket->Translate()->t('The default is empty'),
            '#attributes'       => [
                'checked'           => self::$Basket->getSettings('active_services', 'delivery_default.0')
            ],          
            '#parents'          => ['active_default'],
            '#return_value'     => 0,
        ];
        $form['config_wrap'] = [
            '#type'         => 'container',
            '#states'       => [
                'visible'       => [
                    'input[name="delivery_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('Price'),
                    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('delivery'))){
            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', 'delivery.'.$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', 'delivery_default.'.$result->id)
                        ],          
                        '#parents'          => ['active_default'],
                        '#return_value'     => $result->id,
                    ],
                    'price'             => [
                        '#type'             => 'inline_template',
                        '#template'         => '{% if currency.name and term.delivery_sum %}{{ term.delivery_sum|number_format(2, \',\', \' \') }} {{ basket_t(currency.name) }}{% else %}- - -{% endif %}',
                        '#context'          => [
                            'term'              => $result,
                            'currency'          => !empty($result->delivery_currency) ? self::$Basket->Currency()->load($result->delivery_currency) : NULL
                        ]
                    ],
                    '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_delivery'])->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['delivery_widget'] = [
            '#type'         => 'select',
            '#title'        => t('Widget'),
            '#options'      => [
                'select'        => t('Select list'),
                'radios'        => t('Radios')
            ],
            '#default_value'=> self::$Basket->getSettings('enabled_services', 'delivery_widget'),
            '#states'       => [
                'visible'       => [
                    'input[name="delivery_enabled"]' => ['checked' => TRUE]
                ]
            ],
        ];
        $form['actions'] = [
            '#type'         => 'actions',
            'submit'        => [
                '#type'         => 'submit',
                '#value'        => self::$Basket->Translate()->t('Save'),
                '#ajax'         => [
                    'wrapper'       => 'basket_delivery_list_settings_form',
                    'callback'      => '::ajaxSubmit'
                ]
            ]
        ];
        return $form;
    }
    private static function getSettingsInfo($result){
        $items = [];
        if(!empty(self::$ServicesSettings[$result->id]) && !empty($system = self::$Services[self::$ServicesSettings[$result->id]])){
                
            $items = \Drupal::service('BasketDeliverySettings')->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()
                        ]
                    ];
                }
            }
        }
        return [
            '#theme'            => 'item_list',
            '#list_type'        => 'ul',
            '#wrapper_attributes'=> [
                'class'             => ['settings_list_block']
            ],
            '#items'            => $items
        ];
    }
    public function submitForm(array &$form, FormStateInterface $form_state){
        // enabled_services
        self::$Basket->setSettings(
            'enabled_services', 
            'delivery', 
            $form_state->getValue('delivery_enabled')
        );
        self::$Basket->setSettings(
            'enabled_services', 
            'delivery_widget', 
            $form_state->getValue('delivery_widget')
        );
        // Set active settings
        self::$Basket->setSettings(
            'active_services', 
            'delivery', 
            $form_state->getValue('active_config')
        );
        // Set active default
        self::$Basket->setSettings(
            'active_services', 
            'delivery_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;
    }
}
/*
 DeliverySettingsForm
*/
class DeliverySettingsForm 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('delivery_services', self::$term->id);
        }
    }
    public function getFormId(){
        return 'basket_delivery_settings_form';
    }
    public function buildForm(array $form, FormStateInterface $form_state){
        $form += [
            '#prefix'       => '<div id="basket_delivery_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['delivery_sum'] = [
            '#type'         => 'number',
            '#title'        => self::$Basket->Translate()->t('Shipping cost'),
            '#min'          => 0,
            '#step'         => 0.01,
            '#default_value'=> !empty(self::$term->delivery_sum) ? self::$term->delivery_sum : 0
        ];
        $form['delivery_currency'] = [
            '#type'         => 'select',
            '#title'        => self::$Basket->Translate()->t('Currency'),
            '#options'      => self::$Basket->Currency()->getOptions(),
            '#default_value'=> !empty(self::$term->delivery_currency) ? self::$term->delivery_currency : 0
        ];
        $services = [];
        if(!empty($deliverys = \Drupal::service('BasketDelivery')->getDefinitions())){
            foreach ($deliverys as $delivery){
                $services[$delivery['id']] = self::$Basket->Translate(trim($delivery['provider']))->t(trim($delivery['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,
        ];
        /*Service alter*/
        \Drupal::service('BasketDeliverySettings')->deliverySettingsFormAlter($form, $form_state);
        /*---*/
        $form['actions'] = [
            '#type'         => 'actions',
            'submit'        => [
                '#type'         => 'submit',
                '#value'        => self::$Basket->Translate()->t('Save'),
                '#ajax'         => [
                    'wrapper'       => 'basket_delivery_settings_form_ajax_wrap',
                    'callback'      => '::ajaxSubmit'
                ]
            ]
        ];
        return $form;
    }
    public function submitForm(array &$form, FormStateInterface $form_state){
        $values = $form_state->getValues();
        if(!empty($values['tid'])){
            \Drupal::database()->update('basket_terms')
                        ->fields([
                            'name'              => trim($values['name']),
                            'delivery_sum'      => !empty($values['delivery_sum']) ? $values['delivery_sum'] : NULL,
                            'delivery_currency' => !empty($values['delivery_currency']) ? $values['delivery_currency'] : NULL,
                        ])
                        ->condition('id', $values['tid'])
                        ->execute();
        } else {
            $values['tid'] = \Drupal::database()->insert('basket_terms')
                        ->fields([
                            'type'      => 'delivery',
                            'name'      => trim($values['name']),
                            'weight'    => -100,
                            'delivery_sum'      => !empty($values['delivery_sum']) ? $values['delivery_sum'] : NULL,
                            'delivery_currency' => !empty($values['delivery_currency']) ? $values['delivery_currency'] : NULL,
                        ])
                        ->execute();
        }
        /*Update service info*/
        self::$Basket->setSettings(
            'delivery_services', 
            $values['tid'], 
            $form_state->getValue('service')
        );
        $form_state->setValue('tid', $values['tid']);
    }
    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;
        }
    }
}