<?php

namespace Drupal\user_provisioning\Helpers;
/**
 * Provides a ready-made table with ajax add/remove rows button.
 *
 * This class provides you three functionality:
 *
 *    (1) Generate Tables
 *
 *    (2) Generate Add more button
 *
 *    (3) Generate unique id array
 *
 * - - - - - - - - - - - - - - - - - - - - - - - -
 *
 * (1) Generate Tables:
 * You can generate simple table by providing few parameters to function generateTables()
 * This function required following parameters:
 * (i) ID: Unique ID of table useful for ajax operations
 * (ii) fields: Number of fields in table. You can add as many fields as you want. field should be an array in following format
 * @code
 * $fields = [
 *  'first_name' => [
 *     'type' => 'select',
 *  ],
 * 'last_name' => [
 *    'type' => 'textfield',
 *    'placeholder' => 'Last Name of User'
 *  ],
 * 'delete_button' => [
 *    'type' => 'submit',
 *    'submit' => '::removeCallback',
 *    'callback' => '::removeButtonCallback',
 *    'wrapper' => 'names-fieldset-wrapper',
 *    ]
 *  ];
 * (iii) Unique ID array: This is the array which contains array of unique array to print rows
 * (iv) Options: default options to show in the  table
 * (v) Headers (optional): header of the table in the array format
 * (vi) Option to show in drop-down list (optional): This should be an array with following format:
 * @code
 * $select_list = [
 *  1 => [
 *    'first_column_row_1' => 'one',
 *    'first_column_row_2' => 'two',
 *    'first_column_row_3' => 'three',
 *    'first_column_row_4' => 'four',
 *  ]
 *  2 => [
 *    'second_column_row_1' => 'one',
 *    'second_column_row_2' => 'two',
 *    'second_column_row_3' => 'three',
 *    'second_column_row_4' => 'four',
 *  ]
 * ]
 * In above array $select_list -> 1 and 2 denoted column number where you want to show drop-down select list
 *
 * - - - - - - - - - - - - - - - - - - - - - - - -
 *
 * (2) Generate Add more button:
 * You can easily generate add more button by providing few parameters to generateAddButton() function
 * You need to provide name of button, submit function, callback function, text before button etc.
 *
 * - - - - - - - - - - - - - - - - - - - - - - - -
 *
 * (3) Generate unique id array:
 * Unique id array contains array key of each table row, and it is used to print rows of table.
 * This array updates on every ajax call. Use generateAddButton() function to generate this array.
 */

class AjaxTables {

    /**
     * Main function to generate tables
     *
     * @param $id
     * ID of the table, useful for ajax wrapper
     * @param $fields
     * Array of fields to be used in table
     * @param $unique_array
     * Array contains index of rows
     * @param $options
     * Main data to be print in table
     * @param array $headers
     * Header of the table
     * @param array $select_list
     * Options for select element (optional)
     *
     * @return array
     * Returns complete table
     */
    public static function generateTables($id, $fields, $unique_array, $options, array $headers = [], array $select_list=[]) {
        $form['table'] = array(
            '#type' => 'table',
            '#header' => $headers,
            '#prefix' => '<div id="'.$id.'">',
            '#suffix' => '</div>',
        );

        foreach ($unique_array as $row) {
            $form['table'][$row]= static::generateFields($fields, $row, $select_list);
            foreach ($fields as $key => $value) {
                if($value['type']!='submit') {
                    $form['table'][$row][$key]['#default_value'] = $options[$row][$key] ?? '';
                }
                if(count($unique_array) == 1 && $value['type'] == 'submit') {
                    unset($form['table'][$row][$key]);
                }
            }
        }

        return $form['table'];
    }

    /**
     * The $option parameter should be following format
     * $option = ['unique_id' => ['field_name' => 'field_value']]
     * @param $form_state_value
     * Value of unique array in form_state
     * @param $options
     * The options array to be print in table format
     * @return int[]|string[]
     * Returns array of unique id array
     */
    public static function getUniqueID($form_state_value, $options) {
        if(empty($form_state_value)) {
            $form_state_value = array_keys($options);
            if(empty($options)) {
                $uuid_service = \Drupal::service('uuid');
                $form_state_value[]  = $uuid_service->generate();
            }
        }
        return $form_state_value;
    }


    /**
     * @param $fields
     * Fields to be generated
     * @param $row
     * Unique ID of the row
     * @param $select_list
     * Options for form type select (optional)
     * @return array
     */
    private static function generateFields($fields, $row, $select_list) {
        $form = [];
        $count = 1;
        foreach ($fields as $key => $value) {
            $form[$key] = [
                '#type' => $value['type'],
                '#title' => $value['title'] ?? '',
                '#attributes' =>  $value['attributes'] ?? [],
                '#description' =>  $value['description'] ?? '',
                '#disabled' =>  $value['disabled'] ?? false,
            ];

            if(isset($value['prefix'])) {
                $form[$key]['#prefix'] =  $value['prefix'];
            }

            if(isset($value['suffix'])) {
                $form[$key]['#suffix'] =  $value['suffix'];
            }

            if($value['type'] == 'select') {
                $form[$key]['#options'] = $select_list[$count];
                $form[$key]['#empty_option'] = t('Select Attribute Value');
            }

            if($value['type'] == 'textfield') {
                $form[$key]['#size'] = 15;
            }

            if($value['type'] == 'submit') {
                unset( $form[$key]['#title']);
                $form[$key]['#value'] = '-';
                $form[$key]['#name'] = $row;
                $form[$key]['#attributes'] = ['class' => ['button--small button--primary'], 'style' => 'cursor: not-allowed;'];
                $form[$key]['#attributes']['disabled'] = $value['disabled'] ?? false;
                $form[$key]['#submit'] = [$value['submit']];
                $form[$key]['#ajax'] = [
                    'callback' => $value['callback'],
                    'wrapper' => $value['wrapper'],
                    'progress' => [
                        'type' => 'fullscreen',
                    ]
                ];
            }
            $count++;
        }
        return $form;
    }

    /**
     * This function is automatically generate ajax add more button.
     * If you have to generate more than one buttons on same form then use different name for button
     *
     * @param $value
     * Value of the add button
     * @param $submit
     * Function to call of ajax call where logic of add row is written.
     *  Function name should be in '::nameOfFunction' format
     * @param $callback
     * Callback function in ajax call.
     *  Function name should be in '::callbackFunction' format
     * @param $wrapper
     * An ajax wrapper
     * @param string $text_before_button
     * Use this parameter If you have to add some text before the add button (optional)
     * @param bool $disabled
     * Status of button i.e disabled or enabled
     * @return array
     * Ajax add more button
     */
    public static function generateAddButton($value, $submit, $callback, $wrapper, string $text_before_button = '', bool $disabled=false ) {
        $form['text_before_button'] = [
            '#markup'  => t('<b>'.$text_before_button.'&#8194; </b>'),
            '#prefix'  => '<div class="container-inline">',
        ];

        $form['button'] = [
            '#type' => 'submit',
            '#suffix' => '</div>',
            '#attributes' => ['class' => ['button--small button--primary']],
            '#value' => $value,
            '#submit' => [$submit],
            '#disabled' => $disabled,
            '#ajax' => [
                'callback' => $callback,
                'wrapper' => $wrapper,
                'progress' => [
                    'type' => 'fullscreen',
                ]
            ]
        ];
        return $form;
    }
}

