<?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 NodeTypes{

	protected static $Basket;
    protected static $BasketTranslate;
    protected static $getFieldNodeType;

	public static function construct(){
		self::$Basket = \Drupal::service('Basket');
        self::$BasketTranslate = self::$Basket->Translate();
	}
	public static function table(){
        self::construct();
		return [
            '#prefix'       => '<div class="basket_table_wrap">',
            '#suffix'       => '</div>',
            'table'         => [
                '#prefix'       => '<div class="b_content">',
                '#suffix'       => '</div>',
                [
                    '#theme'        => 'table',
                    '#header'       => [
                        self::$BasketTranslate->t('Material type'),
                        self::$BasketTranslate->t('Field pictures'),
                        self::$BasketTranslate->t('Field price'),
                        self::$BasketTranslate->t('Field count'),
                        self::$BasketTranslate->t('Extra fields'),
                        ''
                    ],
                    '#rows'         => self::getRows(),
                    '#empty'        => self::$BasketTranslate->t('The list is empty.')
                ]
            ],
            'CreateLink'        => [
                '#type'         => 'inline_template',
                '#template'     => '<a href="javascript:void(0);" onclick="{{onclick}}" data-post="{{post}}" id="CreateLink">+ {{text}}</a>',
                '#context'      => [
                    'text'          => self::$BasketTranslate->t('Create'),
                    'onclick'       => 'basket_admin_ajax_link(this, \''.Url::fromRoute('basket.admin.pages', ['page_type' => 'api-add_node_type'])->toString().'\')',
                    'post'          => json_encode([])
                ],
            ]
        ];
  	}
    private static function getRows(){
        $rows = [];
        // ---
        $results = \Drupal::database()->select('basket_node_types', 'n')
                                ->fields('n')
                                ->execute()->fetchAll();
        if(!empty($results)){
            $node_types = \Drupal\node\Entity\NodeType::loadMultiple();
            foreach ($results as $result){
                if(empty($node_types[$result->type]))   continue;

                $rows[] = [
                    [
                        'data'      => [
                            '#markup'       => '<b>'.$node_types[$result->type]->label().'</b> ('.$result->type.')'
                        ]
                    ],
                    self::getFieldName($result->type, [$result->image_field], self::$Basket->BasketFieldImages),
                    self::getFieldName($result->type, [$result->price_field], self::$Basket->BasketFieldPrices),
                    self::getFieldName($result->type, [$result->count_field], self::$Basket->BasketFieldCount),
                    self::getExtraFields($result->extra_fields),
                    [
                        'data'      => [
                            '#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-add_node_type'])->toString().'\')',
                                        'post'          => json_encode([
                                            'node_type'     => $result->type
                                        ]),
                                    ],[
                                        '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_node_type'])->toString().'\')',
                                        'post'          => json_encode([
                                            'delete_node_type'=> $result->type
                                        ]),
                                    ]
                                ]
                            ]
                        ],
                        'class'         => ['td_settings_row']
                    ]
                ];
            }
        }
        // ---
        return $rows;
    }
    private static function getFieldName($nodeType, $fieldNames, $fieldsTypes = []){
        $items = [];
        foreach ($fieldNames as $fieldName){
            $getFields = self::$Basket->getNodeTypeFields($nodeType, $fieldsTypes);
            if(!empty($getFields[$fieldName])){
                $items[] = str_replace('[', '<br/>[', $getFields[$fieldName]);
            }
        }
        if(!empty($items)){
            return [
                'data'      => [
                    '#markup'   => implode('<br/><br/>', $items)
                ],
                'title'     => self::$BasketTranslate->t('Field can be overridden')
            ];
        }
        return [
            'data'      => self::$BasketTranslate->t('Not specified'),
            'class'     => ['not_specified'],
            'title'     => self::$BasketTranslate->t('Field can be overridden')
        ];
    }
    private static function getExtraFields($extra_fields){
        $fields = [];
        if(!empty($extra_fields)){
            foreach (unserialize($extra_fields) as $key => $value){
                if(empty($value['on']))  continue;
                switch($key){
                    case'add':
                        $fields[$key] = [
                            '#type'         => 'inline_template',
                            '#template'     => '<b>{{label|raw}}</b>{% if alls %}
                            <ul>
                                {% for all in alls %}
                                    <li>{{ all|raw }}</li>
                                {% endfor %}
                            </ul>
                            {% endif %}',
                            '#context'      => [
                                'label'         => self::$BasketTranslate->t('Add button'),
                                'alls'          => []
                            ]
                        ];
                        if(!empty($value['text'])){
                            $translate = self::$BasketTranslate->getTranslateLink(trim($value['text']));
                            $fields[$key]['#context']['alls'][] = self::$BasketTranslate->t('Button text')
                                                                    .': '
                                                                    .$value['text']
                                                                    .' '
                                                                    .\Drupal::service('renderer')->render($translate);
                        }
                        if(!empty($value['count'])){
                            $fields[$key]['#context']['alls'][] = self::$BasketTranslate->t('Show + / -');
                        }
                    break;
                    case'add_params':
                        $fields[$key] = [
                            '#markup'       => '<b>'.self::$BasketTranslate->t('Selection of parameters').'</b>'
                        ];
                    break;
                    case'add_count_sum':
                        $fields[$key] = [
                            '#markup'       => '<b>'.self::$BasketTranslate->t('Summarize products when adding to cart').'</b>'
                        ];
                    break;
                    default:
                        $fields[$key] = [];
                        /*Alter*/
                        \Drupal::moduleHandler()->alter('basket_node_type_extra_fields_list', $fields[$key], $value, $key);
                        /**/
                    break;
                }
            }
        }
        return [
            'data'      => $fields
        ];
    }
    public static function ApiResponseAlter(&$response){
        self::construct();
        if(!empty($_POST['delete_node_type'])){
            if(!empty($_POST['confirm'])){
                \Drupal::database()->delete('basket_node_types')
                            ->condition('type', $_POST['delete_node_type'])
                            ->execute();
                $response->addCommand(new InvokeCommand('body', 'append', ['<script>location.reload();</script>']));
            } else {
                \Drupal::service('BasketPopup')->openModal(
                    $response,
                    self::$BasketTranslate->t('Delete').' "'.$_POST['delete_node_type'].'"',
                    \Drupal\basket\Admin\BasketDeleteConfirm::confirmContent([
                        'onclick'       => 'basket_admin_ajax_link(this, \''.Url::fromRoute('basket.admin.pages', ['page_type' => 'api-delete_node_type'])->toString().'\')',
                        'post'          => json_encode([
                            'delete_node_type'    => $_POST['delete_node_type'],
                            'confirm'             => 1
                        ]),
                    ]),
                    [
                        'width' => 400,
                        'class' => ['basket_add_popup']
                    ]
                );
            }
        } else {
            \Drupal::service('BasketPopup')->openModal(
                $response,
                empty($_POST['node_type']) ? self::$BasketTranslate->t('Create') : self::$BasketTranslate->t('Edit'),
                \Drupal::formBuilder()->getForm(
                    new ExtraFieldsNodeTypeForm(),
                    !empty($_POST['node_type']) ? $_POST['node_type'] : NULL
                ),[
                    'width' => 900,
                    'class' => ['basket_add_popup']
                ]
            );
        }
    }
}
class ExtraFieldsNodeTypeForm extends FormBase{

    protected static $Basket;
    protected static $BasketTranslate;

    public function __construct(){
        self::$Basket = \Drupal::service('Basket');
        self::$BasketTranslate = self::$Basket->Translate();
    }
    public function getFormId(){
        return 'basket_node_type_fields_edit_form';
    }
    public function buildForm(array $form, FormStateInterface $form_state, $NodeTypeActive = NULL){
        $form['#prefix'] = '<div id="basket_extra_fields_node_type_edit_form_ajax_wrap">';
        $form['#suffix'] = '</div>';
        // ---
        $values = $form_state->getValues();
        if(empty($values) && !empty($NodeTypeActive)){
            $values['node_type'] = $NodeTypeActive;
            $NodeTypeActive = \Drupal::database()->select('basket_node_types', 'n')
                                            ->fields('n')
                                            ->condition('n.type', $NodeTypeActive)
                                            ->execute()->fetchObject();
            if(!empty($NodeTypeActive->extra_fields)){
                $NodeTypeActive->extra_fields = unserialize($NodeTypeActive->extra_fields);
            }
        }
        // ---
        $ajaxReload = [
            'wrapper'       => 'basket_extra_fields_node_type_edit_form_ajax_wrap',
            'callback'      => '::ajaxReload'
        ];
        $form['status_messages'] = [
            '#type'         => 'status_messages'
        ];
        $form['node_type'] = [
            '#type'         => 'select',
            '#title'        => self::$BasketTranslate->t('Material type'),
            '#required'     => TRUE,
            '#options'      => self::getNodeTypesList(),
            '#ajax'         => $ajaxReload,
            '#default_value'=> !empty($NodeTypeActive->type) ? $NodeTypeActive->type : NULL
        ];
        if(!empty($values['node_type'])){
            $form['image_field'] = [
                '#type'         => 'select',
                '#title'        => self::$BasketTranslate->t('Field pictures'),
                '#options'      => self::$Basket->getNodeTypeFields($values['node_type'], self::$Basket->BasketFieldImages),
                '#empty_option' => t('- Select -'),
                '#default_value'=> !empty($NodeTypeActive->image_field) ? $NodeTypeActive->image_field : NULL
            ];
            $form['price_field'] = [
                '#type'         => 'select',
                '#title'        => self::$BasketTranslate->t('Field price'),
                '#options'      => self::$Basket->getNodeTypeFields($values['node_type'], self::$Basket->BasketFieldPrices),
                '#empty_option' => t('- Select -'),
                '#default_value'=> !empty($NodeTypeActive->price_field) ? $NodeTypeActive->price_field : NULL
            ];
            $form['count_field'] = [
                '#type'         => 'select',
                '#title'        => self::$BasketTranslate->t('Field count'),
                '#options'      => self::$Basket->getNodeTypeFields($values['node_type'], self::$Basket->BasketFieldCount),
                '#empty_option' => t('- Select -'),
                '#default_value'=> !empty($NodeTypeActive->count_field) ? $NodeTypeActive->count_field : NULL
            ];
            $form['extra_fields'] = [
                '#type'         => 'details',
                '#open'         => TRUE,
                '#title'        => self::$BasketTranslate->t('Extra fields'),
                'table'         => [
                    '#type'             => 'table',
                    '#NodeTypeActive'   => $NodeTypeActive,
                    [
                        [
                            '#type'         => 'checkbox',
                            '#title'        => self::$BasketTranslate->t('Add button'),
                            '#parents'      => ['extra_fields', 'add', 'on'],
                            '#default_value'=> !empty($NodeTypeActive->extra_fields['add']['on']) ? 1 : 0
                        ],[
                            '#type'         => 'textfield',
                            '#attributes'   => [
                                'placeholder'   => self::$BasketTranslate->t('Button text')
                            ],
                            '#parents'      => ['extra_fields', 'add', 'text'],
                            '#states'       => [
                                'visible'       => [
                                    'input[name="extra_fields[add][on]"]' => ['checked' => TRUE]
                                ]
                            ],
                            '#default_value'=> !empty($NodeTypeActive->extra_fields['add']['text']) ? $NodeTypeActive->extra_fields['add']['text'] : ''
                        ],[
                            '#type'         => 'checkbox',
                            '#title'        => self::$BasketTranslate->t('Show + / -'),
                            '#parents'      => ['extra_fields', 'add', 'count'],
                            '#states'       => [
                                'visible'       => [
                                    'input[name="extra_fields[add][on]"]' => ['checked' => TRUE]
                                ]
                            ],
                            '#default_value'=> !empty($NodeTypeActive->extra_fields['add']['count']) ? 1 : 0,
                            '#wrapper_attributes' => ['colspan' => 2]
                        ]
                    ],[
                        [
                            '#type'         => 'checkbox',
                            '#title'        => self::$BasketTranslate->t('Summarize products when adding to cart'),
                            '#parents'      => ['extra_fields', 'add_count_sum', 'on'],
                            '#default_value'=> !empty($NodeTypeActive->extra_fields['add_count_sum']['on']) ? 1 : 0,
                            '#wrapper_attributes' => ['colspan' => 5]
                        ] 
                    ],[
                        [
                            '#type'         => 'checkbox',
                            '#title'        => self::$BasketTranslate->t('Selection of parameters'),
                            '#parents'      => ['extra_fields', 'add_params', 'on'],
                            '#default_value'=> !empty($NodeTypeActive->extra_fields['add_params']['on']) ? 1 : 0,
                            '#wrapper_attributes' => ['colspan' => 5]
                        ]
                    ]
                ]
            ];
            /*Alter*/
            \Drupal::moduleHandler()->alter('basket_node_type_extra_fields_form', $form['extra_fields']['table'], $form_state);
            /**/
        }
        $form['actions'] = [
            '#type'         => 'actions',
            'submit'        => [
                '#type'         => 'submit',
                '#value'        => self::$BasketTranslate->t('Save'),
                '#ajax'         => $ajaxReload
            ]
        ];
        return $form;
    }
    public function submitForm(array &$form, FormStateInterface $form_state){

    }
    public function ajaxReload(array &$form, FormStateInterface $form_state){
        if ($form_state->isSubmitted() && !$form_state->getErrors()){
            $values = $form_state->getValues();
            \Drupal::database()->merge('basket_node_types')
                        ->key([
                            'type'              => $values['node_type']
                        ])
                        ->fields([
                            'type'              => $values['node_type'],
                            'image_field'       => !empty($values['image_field'])       ? $values['image_field']                : NULL,
                            'price_field'       => !empty($values['price_field'])       ? $values['price_field']                : NULL,
                            'count_field'       => !empty($values['count_field'])       ? $values['count_field']                : NULL,
                            'extra_fields'      => !empty($values['extra_fields'])      ? serialize($values['extra_fields'])    : NULL,
                        ])
                        ->execute();
            drupal_flush_all_caches();
            $response = new AjaxResponse();
            $response->addCommand(new InvokeCommand('body', 'append', ['<script>location.reload();</script>']));
            return $response;
        }
        return $form;
    }
    public static function getNodeTypesList(){
        $node_types = \Drupal\node\Entity\NodeType::loadMultiple();
        $options = [];
        foreach ($node_types as $node_type){
            if($node_type->id() == 'basket_order') continue;
            $options[$node_type->id()] = $node_type->label();
        }
        return $options;
    }
}
