<?php

/**
 * @file
 * Contains \Drupal\zone_data\Form\ZoneBuildUi.
 */

namespace Drupal\zone_data\Form;

use Drupal\node\Entity;
use Drupal\node\Entity\Node;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\taxonomy\Entity\Term;

/**
 * Directory Search form.
 */

class ZoneBuildUi extends FormBase
{

    /**
     * {@inheritdoc}
     */

    public function getFormId()
    {
        return 'zone_build_form';
    }

    /**
     * @param array $form
     * @param FormStateInterface $form_state
     * @return array
     */
    public function buildForm(array $form, FormStateInterface $form_state)
    {
//        $config = $this->config('zone_data.settings');

        $form['sector'] = array(
            '#type' => 'entity_autocomplete',
            '#placeholder' => 'Sector',
            '#entity_type' => 'taxonomy_term',
            '#target_type' => 'taxonomy_term',
            '#bundles' => array('sector'),
            '#autocomplete_path' => 'entity-autocomplete/taxonomy/sector/',
            '#selection_settings' => ['target_bundles' => ['sector']],
        );

        $form['boutiqueNames'] = array(
            '#type' => 'textarea',
            '#title' => $this->t('Boutique Names'),
//            '#default_value' => $config->get('names'),
        );

        $form['geoJson'] = array(
            '#type' => 'textarea',
            '#title' => $this->t('OSM GeoJson Data'),
//            '#default_value' => $config->get('geo_json'),
        );

        $form['submit'] = array(
            '#type' => 'submit',
            '#value' => t('Execute'),
        );


//        return parent::buildForm($form, $form_state);
        return $form;
    }


    public function submitForm(array &$form, FormStateInterface $form_state)
    {
//      $config = \Drupal::service('config.factory')->getEditable('zone_data.settings');
//      $config->set('names', $form_state->getValue('boutiqueNames'))->set('geo_json', $form_state->getValue('geoJson'))
//          ->save();
//      $myVar = $form_state;
        $jsonValid = false;
        $boutiquesUpdated = array();
        $storeList = normalizeChars($form_state->getValue('boutiqueNames'));
        $storesArr = explode(PHP_EOL, $storeList);
        $file = normalizeChars($form_state->getValue('geoJson'));
        $sector = $form_state->getValue('sector');
        $matchedStores = 0;
        $matchedNodes = 0;
        $storesNotFound = array();
        $nodesNotFound = array();
        $createdZones = array();

        $sectorName = db_query("SELECT name from taxonomy_term_field_data WHERE tid = :tid ", array(
                                                     ':tid' => $sector)
                                                     )->fetchField();

        $zoneQuery = db_query("SELECT name FROM taxonomy_term_field_data WHERE name like :name", array(
            ':name' => $sectorName . '%',
        ))->fetchAll();
        $zCount = count($zoneQuery);
        $zoneMax = 0;
        if (count($zCount) > 0) {
            for ($zi = 0; $zi < $zCount; $zi++) {
                $zoneQuery[$zi]->name = preg_replace('/\D/', '', $zoneQuery[$zi]->name);
            }
            $zoneMax = max($zoneQuery)->name + 1;
        }

        if (!empty($geojson = json_decode($file))) {
            $numFeatures = count($geojson->features);
            $jsonValid = true;

            foreach ($storesArr as $store) {
                $match = false;
                foreach ($geojson->features as $feature) {
                    if (isset($feature->properties->name)) {
                        $name = $feature->properties->name;
                        if (trim(strtolower($store)) === trim(strtolower($feature->properties->name))) {
                            $match = true;
                            $matchedStores++;

                            $nQuery = db_query('SELECT nid FROM node_field_data WHERE title LIKE :title AND type = :type AND langcode = :langcode', array(
                                ':title' => $store,
                                ':type' => 'boutique',
                                ':langcode' => 'en',
                            ))->fetchField();

                            if ($nQuery > 0) {
                                $featureData = json_encode($feature->geometry);
                                $matchedNodes++;

                                $term = \Drupal\taxonomy\Entity\Term::create([
                                    'name' => $sectorName . $zoneMax,
                                    'vid' => 'zone',
                                ])->save();
                                if ($term) {
                                    $tidQ = array_values(\Drupal::entityQuery('taxonomy_term')
                                        ->condition('vid', 'zone')
                                        ->condition('name', $sectorName . $zoneMax)
                                        ->execute());
                                }
                                if ($tidQ != null && is_array($tidQ) && count($tidQ) > 0) {
                                    $zoneNodeSaveAttempt = null;
                                    $levels = isset($feature->properties->level) ? $feature->properties->level : 1;
                                        $zoneNode = Node::create([
                                            'type' => 'zone',
                                            'body' => $name,
                                            'title' => $sectorName . $zoneMax,
                                            'field_sector_code' => 55,
                                            'field_feature_data' => $featureData,
                                            'field_zone_code' => $tidQ[0],
                                            'field_levels' => $levels,
                                        ]);

                                    $zoneNodeSaveAttempt = $zoneNode->save();

                                    if ($zoneNodeSaveAttempt === 1 || $zoneNodeSaveAttempt === 2) {
                                        $createdZones[] = $name;
                                        $boutiqueNode = Node::load($nQuery);
                                        $boutiqueNode->field_zone_code = $tidQ[0];
                                        $boutiqueNodeSaveAttempt = $boutiqueNode->save();

                                        if ($boutiqueNodeSaveAttempt === 1 || $boutiqueNodeSaveAttempt === 2) {
                                            $boutiquesUpdated[] = $name;
                                        }
                                    }


                                } else {
                                    $errMsg = 'zone term was not created for: ' . $store;
                                    \Drupal::logger('zone_data')->error($errMsg);
                                }


                            } else {
                                $nodesNotFound[] = $store;
                            }
                        }
                    }
                }
                if ($match == false) {
                    $storesNotFound[] = $store;
                    $logStr = '';
                    foreach ($storesNotFound as $storeName) {
                        $logStr .= $storeName . ', ';
                    }
                    $logStr = substr($logStr, -2);
                    $errMsgAll = 'The following stores did not have zones created for them: ' . $logStr;
                    \Drupal::logger('zone_data')->error($errMsgAll);
                    drupal_set_message('Error adding zones');


                }
                $zoneMax++;
            }
        }
        if ($jsonValid) { drupal_set_message('Zone build successful'); } else { drupal_set_message('Invalid GeoJSON');}

        return $createdZones;

    }



    public function normalizeChars($s) {
        $replace = array(
            'Ă'=>'A', 'Ą'=>'A', 'À'=>'A', 'Ã'=>'A', 'Á'=>'A', 'Æ'=>'A', 'Â'=>'A', 'Å'=>'A', 'Ä'=>'Ae',
            'È'=>'E', 'Ę'=>'E', 'É'=>'E', 'Ë'=>'E', 'Ê'=>'E',
            'İ'=>'I', 'Ï'=>'I', 'Î'=>'I', 'Í'=>'I', 'Ì'=>'I',
            'Ù'=>'U', 'Û'=>'U', 'Ú'=>'U', 'Ü'=>'Ue',
            'â'=>'a', 'ǎ'=>'a', 'ą'=>'a', 'á'=>'a', 'ă'=>'a', 'ã'=>'a', 'Ǎ'=>'a', 'а'=>'a', 'А'=>'a', 'å'=>'a', 'à'=>'a', 'א'=>'a', 'Ǻ'=>'a', 'Ā'=>'a', 'ǻ'=>'a', 'ā'=>'a', 'ä'=>'ae', 'æ'=>'ae', 'Ǽ'=>'ae', 'ǽ'=>'ae',
            'ĉ'=>'c', 'Ĉ'=>'c', 'Ċ'=>'c', 'ć'=>'c', 'ç'=>'c', 'ц'=>'c', 'צ'=>'c', 'ċ'=>'c', 'Ц'=>'c', 'Č'=>'c', 'č'=>'c', 'Ч'=>'ch', 'ч'=>'ch',
            'є'=>'e', 'ע'=>'e', 'е'=>'e', 'Е'=>'e', 'Ə'=>'e', 'ę'=>'e', 'ĕ'=>'e', 'ē'=>'e', 'Ē'=>'e', 'Ė'=>'e', 'ė'=>'e', 'ě'=>'e', 'Ě'=>'e', 'Є'=>'e', 'Ĕ'=>'e', 'ê'=>'e', 'ə'=>'e', 'è'=>'e', 'ë'=>'e', 'é'=>'e',
            'î'=>'i', 'ï'=>'i', 'í'=>'i', 'ì'=>'i', 'į'=>'i', 'ĭ'=>'i', 'ı'=>'i', 'Ĭ'=>'i', 'И'=>'i', 'ĩ'=>'i', 'ǐ'=>'i', 'Ĩ'=>'i', 'Ǐ'=>'i', 'и'=>'i', 'Į'=>'i', 'י'=>'i', 'Ї'=>'i', 'Ī'=>'i', 'І'=>'i', 'ї'=>'i', 'і'=>'i', 'ī'=>'i', 'ĳ'=>'ij', 'Ĳ'=>'ij',
            'о'=>'o', 'О'=>'o', 'ő'=>'o', 'õ'=>'o', 'ô'=>'o', 'Ő'=>'o', 'ŏ'=>'o', 'Ŏ'=>'o', 'Ō'=>'o', 'ō'=>'o', 'ø'=>'o', 'ǿ'=>'o', 'ǒ'=>'o', 'ò'=>'o', 'Ǿ'=>'o', 'Ǒ'=>'o', 'ơ'=>'o', 'ó'=>'o', 'Ơ'=>'o', 'œ'=>'oe', 'Œ'=>'oe', 'ö'=>'oe',
            'ū'=>'u', 'у'=>'u', 'Ũ'=>'u', 'ũ'=>'u', 'Ư'=>'u', 'ư'=>'u', 'Ū'=>'u', 'Ǔ'=>'u', 'ų'=>'u', 'Ų'=>'u', 'ŭ'=>'u', 'Ŭ'=>'u', 'Ů'=>'u', 'ů'=>'u', 'ű'=>'u', 'Ű'=>'u', 'Ǖ'=>'u', 'ǔ'=>'u', 'Ǜ'=>'u', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'У'=>'u', 'ǚ'=>'u', 'ǜ'=>'u', 'Ǚ'=>'u', 'Ǘ'=>'u', 'ǖ'=>'u', 'ǘ'=>'u', 'ü'=>'ue',
        );
        return strtr($s, $replace);
    }


    /**
     * Gets the configuration names that will be editable.
     *THIS WAS REMOVED AS WE DECIDED AGAINST EXTENDING THE CONFIGFORMBASE CLASS, INSTEAD OPTING FOR A NORMAL FORM
     * @return array
     *   An array of configuration object names that are editable if called in
     *   conjunction with the trait's config() method.
     */
//    protected function getEditableConfigNames()
//    {
//        return [
//            'zone_data.settings',
//        ];
//    }
}