<?php


class SupsysticTablesPro_Tables_Module extends SupsysticTables_Tables_Module
{
	public $useEditableFields = array();
	public $useHistory = false;
	public $userId = false;

	public function onInit()
    {
		$this->updateConfig();
        $this->setOverloadController(true);
        parent::onInit();

		$dispatcher = $this->getEnvironment()->getDispatcher();
		$dispatcher->on('before_table_render', array($this, 'loadTableAssets'));
		$dispatcher->on('tables_get', array($this, 'getConditionsData'));

        $this->renderToolbar();
		$this->addEditableFieldsFeature();
		$this->addConditionalFormattingFeature();
		//$this->addDBTableSource();
		$this->filterTableHistorySection();
		$this->filterTableSourceSection();
    }

	private function updateConfig() {
		$config = $this->getEnvironment()->getConfig();
		$config->add('shortcode_global_page_search_name', $config->get('shortcode_prefix') . '-global-page-search');
		$config->add('shortcode_assets_load', $config->get('shortcode_prefix') . '-assets');
	}

	protected function registerShortcodes() {
		parent::registerShortcodes();
		$config = $this->getEnvironment()->getConfig();

		add_shortcode($config->get('shortcode_global_page_search_name'), array($this, 'doGlobalPageSearchShortcode'));
		add_shortcode($config->get('shortcode_assets_load'), array($this, 'doLoadAssetsShortcode'));
	}

	public function doGlobalPageSearchShortcode($attributes) {
		$twig = $this->getEnvironment()->getTwig();
		return $twig->render('@tables_pro/shortcode_global_page_search.twig', array());
	}

	public function doLoadAssetsShortcode($attributes) {
		$ui = $this->getEnvironment()->getModule('ui');
        $assets = array_filter($ui->getAssets(), array($this, 'filterAssets'));
        if(count($assets) > 0) {
            foreach($assets as $asset) {
                add_action('wp_footer', array($asset, 'load'));
            }
        }
        wp_enqueue_script('tables.conditions.js');
        wp_enqueue_style('supsystic-jquery-ui');
		wp_enqueue_script('jquery-ui-datepicker');
		wp_enqueue_style('supsystic-font-awesome');
		wp_enqueue_style('supsystic-tooltipster');
		wp_enqueue_script('supsystic-tooltipster');
		$this->getEnvironment()->getModule('diagram')->connectDiagramAssets('zing');
	}

	public function render($id, $settings = false) {
		$this->useEditableFields[$id] = $this->checkEditableFieldsAbility($id);

		wp_localize_script('tables-core', 'useEdit', $this->useEditableFields);
		/*wp_localize_script('core.pro.js', 'rulejsLibraries', array(
			'libs' => $this->getLocationUrl() . '/assets/libraries/ruleJS/ruleJS.lib.full.js',
			'parser' => $this->getLocationUrl() . '/assets/libraries/ruleJS/parser.js',
			'rulejs' => $this->getLocationUrl() . '/assets/libraries/ruleJS/ruleJS.js',
		));*/

        $environment = $this->getEnvironment();
        $core = $environment->getModule('core');
        $tables = $core->getModelsFactory()->get('tables');
        $table = $tables->getById($id);

        if (isset($table->settings['allowedFileTypes'])) {
            wp_localize_script('tables-core', 'dtb_allowedFileTypes', $table->settings['allowedFileTypes']);
        }

		if($this->useHistory) {
			if(!$this->userId) {
				$environment = $this->getEnvironment();
				$user = $environment->getModule('ui')->getCurrentUserInfo();
				$this->userId = (int) $user->ID;
			}
			if($this->userId) {
				$period = !empty($this->historyData['period']) ? $this->historyData['period'] : null;
				try {
					$history = $this->getHistoryModel()->getUserTableHistory($this->userId, $id, $period);
				} catch (RuntimeException $e) {
					return $e->getMessage();
				} catch (Exception $e) {
					return sprintf($this->translate('Failed to get table rows: %s'), $e->getMessage());
				}
				$this->isFromHistory = $history->data;
				foreach($history as $k => $v) {
					if($k == 'data') continue;
					$this->historyData[$k] = $v;
				}
			} else {
				$this->checkSpreadsheet = true;
			}
		} else {
			$this->checkSpreadsheet = true;
		}

		$renderData = parent::render($id, $settings);
		if(!$this->isPreview) {
			$inlineJS = '';
			$commonSettings = get_option('supsystic_tbl_settings');
			if(!empty($commonSettings['load_by_ajax_enabled'])) {
				$renderData .= '<script type="text/javascript">if(typeof window.supsystic!="undefined" && typeof window.supsystic.Tables!="undefined") window.supsystic.Tables.initTablesOnPage('.$id.');</script>';
			}
		}

		return $renderData;
	}

	public function doShortcode($attributes)
	{
		if (array_key_exists('use_history', $attributes)) {
			$this->useHistory = true;

			if(array_key_exists('period', $attributes)) {
				if(!function_exists('date_create')) {
					return $this->getEnvironment()->translate('You should to use PHP v.5.2.0 or greater to use the period feature for history table.');
				}
				$period = date_create($attributes['period']);
				if($period) {
					$this->historyData['attr_period'] = date_format($period, 'Y-m-d');
					$this->historyData['period'] = $period;
				}
			}
		}

		return parent::doShortcode($attributes);
	}

	public function checkEditableFieldsAbility($id)
	{
		return $this->getController()->checkEditableFieldsAbility($id);
	}

    public function afterUiLoaded(SupsysticTables_Ui_Module $ui)
    {
        parent::afterUiLoaded($ui);
        $version = $this->getConfig()->get('plugin_version_pro');
		$hookName = 'admin_enqueue_scripts';
		$frontendHookName = 'wp_enqueue_scripts';
		$dynamicHookName = is_admin() ? $hookName : $frontendHookName;
		$coreModulePath = $this->getConfig()->get('plugin_url') . '/src/SupsysticTables/Core';
		$coreProModulePath = untrailingslashit(plugin_dir_url(dirname(__FILE__)) . 'Core');

		// Dynamic Styles
		$ui->add(
			$ui->createStyle('supsystic-tables-shortcode-pro')
				->setHookName($dynamicHookName)
				->setExternalSource($this->getProLocationUrl() . '/assets/css/tables.shortcode.pro.css')
				->setVersion($version)
		);

		// Frontend Styles
		$ui->createStyle('supsystic-jquery-ui')
			->setHookName($frontendHookName)
			->setExternalSource($coreProModulePath . '/assets/css/lib/jquery-ui.min.css')
			->setVersion($version)
			->register();

		$ui->createStyle('supsystic-font-awesome')
			->setHookName($frontendHookName)
			->setLocalSource('css/libraries/fontawesome/font-awesome.min.css')
			->setVersion('4.7.0')
			->register();

		$ui->createStyle('supsystic-tooltipster')
			->setHookName($frontendHookName)
			->setExternalSource($coreModulePath . '/assets/css/tooltipster.css')
			->setVersion($version)
			->register();


		// Dynamic Scripts

		// Frontend Scripts
		$ui->createScript('supsystic-tooltipster')
			->setHookName($frontendHookName)
			->setExternalSource($coreModulePath . '/assets/js/jquery.tooltipster.min.js')
			->addDependency('jquery')
			->setVersion($version)
			->register();

		$ui->createScript('tables.conditions.js')
			->setHookName($frontendHookName)
			->setExternalSource($this->getProLocationUrl() . '/assets/js/tables.conditions.js')
			->addDependency('core.pro.js')
			->setVersion($version)
			->register();

        if ($this->isModule('tables', 'view')) {
			// Admin Styles
			$ui->add(
				$ui->createStyle('supsystic-jquery-ui')
					->setHookName($hookName)
					->setSource($coreProModulePath . '/assets/css/lib/jquery-ui.min.css')
					->setVersion($version)
			);
			$ui->add(
				$ui->createStyle('supsystic-tables-editor-pro')
					->setHookName($hookName)
					->setExternalSource($this->getProLocationUrl() . '/assets/css/tables.editor.pro.css')
					->setVersion($version)
			);

			// Admin Scripts
			$ui->add(
				$ui->createScript('jquery-ui-sortable')
					->setHookName($hookName)
			);
			$ui->add(
				$ui->createScript('jquery-ui-datepicker')
					->setHookName($hookName)
			);
			$ui->add(
				$ui->createScript('tables.view.pro.js')
					->setHookName($hookName)
					->setExternalSource($this->getProLocationUrl() . '/assets/js/tables.view.pro.js')
					->setVersion($version)
			);
			$ui->add(
				$ui->createScript('tables.model.pro.js')
					->setHookName($hookName)
					->setExternalSource($this->getProLocationUrl() . '/assets/js/tables.model.pro.js')
					->addDependency('supsystic-tables-tables-model')
					->addDependency('tables.conditions.js')
					->setVersion($version)
			);
			$ui->add(
				$ui->createScript('tables.editor.toolbar.pro.js')
					->setHookName($hookName)
					->setExternalSource($this->getProLocationUrl() . '/assets/js/editor/tables.editor.toolbar.pro.js')
					->setVersion($version)
			);
			$ui->add(
				$ui->createScript('tables.editor.pro.js')
					->setHookName($hookName)
					->setExternalSource($this->getProLocationUrl() . '/assets/js/editor/tables.editor.pro.js')
					->setVersion($version)
			);
			$ui->add(
				$ui->createScript('tables.conditions.js')
					->setHookName($hookName)
					->setExternalSource($this->getProLocationUrl() . '/assets/js/tables.conditions.js')
					->setVersion($version)
			);
        }
    }

	public function getConditionsParams() {
		return array(
			'types' => array(
				'cellIs' => array(
					'label' => 'Cell is',
					'type' => 'cell',
				),
				'containsText' => array(
					'label' => 'Text',
					'type' => 'text',
				),
			),
			'operators' => array(
				'beginsWith' => array(
					'label' => 'begins with',
					'type' => 'text',
					'value' => '^{0}',
				),
				'endsWith' => array(
					'label' => 'ends with',
					'type' => 'text',
					'value' => '{0}$',
				),
				'containsText' => array(
					'label' => 'contains',
					'type' => 'text',
					'value' => '',
				),
				'notContains' => array(
					'label' => 'not contains',
					'type' => 'text',
					'value' => '',
				),
				'equal' => array(
					'label' => 'equals',
					'type' => 'cell',
					'value' => '==',
				),
				'notEqual' => array(
					'label' => 'not equals',
					'type' => 'cell',
					'value' => '!=',
				),
				'greaterThan' => array(
					'label' => 'greater than',
					'type' => 'cell',
					'value' => '>',
				),
				'greaterThanOrEqual' => array(
					'label' => 'greater than or equal',
					'type' => 'cell',
					'value' => '>=',
				),
				'lessThan' => array(
					'label' => 'less than',
					'type' => 'cell',
					'value' => '<',
				),
				'lessThanOrEqual' => array(
					'label' => 'less than or equal',
					'type' => 'cell',
					'value' => '<=',
				),
				'between' => array(
					'label' => 'between',
					'type' => 'cell',
					'value' => '{1} <= {0} && {0} <= {2}',
				),
			),
		);
	}

	public function loadTableAssets($table) {
		if(!is_admin()) {
			if(is_array($table->conditionsData) && is_array($table->conditionsData['conditions']) && sizeof($table->conditionsData['conditions']) > 0) {
				wp_enqueue_script('tables.conditions.js');
			}
			$repeatDatefield = true;
			$repeatFontAwesome = true;
			$repeatTooltipCell = true;
			if(!empty($table->meta['requiredAssets'])) {
				if($repeatDatefield && in_array('datefield',$table->meta['requiredAssets'])) {
					wp_enqueue_style('supsystic-jquery-ui');
					wp_enqueue_script('jquery-ui-datepicker');
					$repeatDatefield = false;
				}
				if($repeatFontAwesome && (in_array('tooltipCell', $table->meta['requiredAssets']) || in_array('collapsibleCell', $table->meta['requiredAssets']))) {
					wp_enqueue_style('supsystic-font-awesome');
					$repeatFontAwesome = false;
				}
				if($repeatTooltipCell && in_array('tooltipCell', $table->meta['requiredAssets'])) {
					wp_enqueue_style('supsystic-tooltipster');
					wp_enqueue_script('supsystic-tooltipster');
					$repeatTooltipCell = false;
				}
			} else {
				if(!empty($table->rows)) {
					$repeat = $repeatDatefield || $repeatFontAwesome || $repeatTooltipCell;
					foreach($table->rows as $key => $row) {
						if(!$repeat) break;
						if(isset($row['cells']) && !empty($row['cells'])) {
							foreach ($row['cells'] as $index => $cell) {
								if(!$repeat) break;
								if(!empty($cell['meta'])) {
									if($repeatDatefield && in_array('datefield', $cell['meta'])) {
										wp_enqueue_style('supsystic-jquery-ui');
										wp_enqueue_script('jquery-ui-datepicker');
										$repeatDatefield = false;
									}
									if($repeatFontAwesome && (in_array('tooltipCell', $cell['meta']) || in_array('collapsibleCell', $cell['meta']))) {
										wp_enqueue_style('supsystic-font-awesome');
										$repeatFontAwesome = false;
									}
									if($repeatTooltipCell && in_array('tooltipCell', $cell['meta'])) {
										wp_enqueue_style('supsystic-tooltipster');
										wp_enqueue_script('supsystic-tooltipster');
										$repeatTooltipCell = false;
									}
									$repeat = $repeatDatefield || $repeatFontAwesome || $repeatTooltipCell;
								}
							}
						}
					}
				}
			}
		}
		return $table;
	}

    /**
     * {@inheritdoc}
     */
    public function getShortcodeTemplate()
    {
        return '@tables_pro/shortcode.twig';
    }

    /**
     * Returns the URL to the PRO version of the module.
     * @return string
     */
    public function getProLocationUrl()
    {
        return untrailingslashit(plugin_dir_url(__FILE__));
    }

    private function renderToolbar()
    {
		$dispatcher = $this->getDispatcher();
		$dispatcher->on('toolbar_rendered', array($this, 'afterToolbarRendered'));
		$dispatcher->on('toolbar_fonts_list', array($this, 'toolbarFontsList'));
		$dispatcher->on('toolbar_frontend_fields', array($this, 'toolbarFrontendFields'));
    }

    public function afterToolbarRendered($table) {
		$this->getTwig()->display('@tables_pro/partials/toolbar.twig',
            array('table' => $table)
        );
    }

	public function toolbarFontsList($table) {
		$fonts_list = array_merge($this->getFontsList(), $this->getStandardFontsList());
		natsort($fonts_list);
		$this->getTwig()->display('@tables_pro/partials/toolbarFontsList.twig',
			array('table' => $table, 'fonts_list' => $fonts_list)
		);
	}

	public function toolbarFrontendFields($table) {
		$this->getTwig()->display('@tables_pro/partials/toolbarFrontendFields.twig',
			array('table' => $table)
		);
	}

	private function addEditableFieldsFeature()
	{
		$dispatcher = $this->getEnvironment()->getDispatcher();
		$dispatcher->on('tables-view-features', array($this, 'renderEditableFieldsFeatures'));
	}

	public function renderEditableFieldsFeatures($table)
	{
		$twig = $this->getEnvironment()->getTwig();
		if (function_exists ( 'wp_roles' )) {
			$roles_name = wp_roles()->role_names;
		} else {
			$roles_name = array();
		}
		$twig->display('@tables_pro/features/editableFields.twig', array('table' => $table, 'wpRoles' => $roles_name, 'fileTypes' => $this->getController()->fileTypes));
	}

	private function addConditionalFormattingFeature() {
		$dispatcher = $this->getEnvironment()->getDispatcher();
		$dispatcher->on('tables-view-features', array($this, 'renderConditionalFormattingFeatures'));
	}

	public function renderConditionalFormattingFeatures($table)
	{
		$twig = $this->getEnvironment()->getTwig();
		$twig->display('@tables_pro/features/conditionalFormatting.twig', array('table' => $table));
	}

	private function filterTableSourceSection()
	{
		$dispatcher = $this->getEnvironment()->getDispatcher();

		$dispatcher->on('table_source_tabs_content_template', array($this, 'onTableSourceTabsContentTemplate'));
		$dispatcher->on('table_source_tabs_content_data', array($this, 'onTableSourceTabsContentData'));
	}

	public function onTableSourceTabsContentTemplate()
	{
		return '@tables_pro/partials/sourceTabContent.twig';
	}

	public function onTableSourceTabsContentData($data)
	{
		if (!array_key_exists('table', $data) || !is_object($data['table'])) {
			return $data;
		}
		$table = $data['table'];

		$dbTablesModel = $this->getDBTablesModel();
		$dbNames = array();
		$dbTables = array();
		$dbFields = array();
		$source = array();
		$error = false;

		if(isset($table->settings['source'])) {
			$source = $table->settings['source'];
			if(!isset($source['database']) || $source['database'] != 'on') {
				unset($source['dbName']);
			}
			if(isset($source['dbName'])) {
				$dbName = $source['dbName'];
			}
			if(isset($source['dbTable'])) {
				$dbTable = $source['dbTable'];
			}
		}

		$result = $dbTablesModel->getDBNames();
		if(isset($result) && is_array($result)) {
			$dbNames = $result;
			array_unshift($dbNames, DB_NAME);
			$dbNames[] = 'External DB';
			if(!isset($dbName) || !in_array($dbName, $dbNames)) {
				$dbName = $dbNames[0];
			}

			$connected = $dbTablesModel->connectToExternalDB($source);
			if($connected === true) {
				$dbTables = $dbTablesModel->getDBTables();
				array_unshift($dbTables, 'SQL Query');
				if(!isset($dbTable) || !in_array($dbTable, $dbTables)) {
					$dbTable = $dbTables[0];
				}

				if($dbTable != 'SQL Query') {
					$dbFields = $dbTablesModel->getFields($dbTable);
				}
			}
		} else {
			$error = $result;
			unset($table->settings['source']['database']);
			$dbNames = array();
		}
		if (function_exists ( 'wp_roles' )) {
			$roles_name = wp_roles()->role_names;
		} else {
			$roles_name = array();
		}
		return array('table' => $table,
				'dbTables' => array('error' => $error, 'names' => $dbNames, 'tables' => $dbTables, 'fields' => $dbFields),
				'wpRoles' => $roles_name);
	}

	/**
	 * Adds filter to the tab content template.
	 * Adds the filter to the table's history content tab.
	 * Filter adds the diagrams for the selected table.
	 */
	private function filterTableHistorySection()
	{
		$dispatcher = $this->getEnvironment()->getDispatcher();

		$dispatcher->on('table_history_tabs_content_template', array($this, 'onTableHistoryTabsContentTemplate'));
		$dispatcher->on('table_history_tabs_content_data', array($this, 'onTableHistoryTabsContentData'));
	}

	/**
	 * Returns new tab content template.
	 * @return string
	 */
	public function onTableHistoryTabsContentTemplate()
	{
		return '@tables_pro/partials/historyTabContent.twig';
	}

	/**
	 * Adds the table's history variable to the template for PRO version.
	 * @param array $data Template data
	 * @return array
	 */
	public function onTableHistoryTabsContentData(array $data = array())
	{
		if (!array_key_exists('table', $data) || !is_object($data['table'])) {
			return $data;
		}
		$historyModel = $this->getHistoryModel();
		$data['historyData'] = $historyModel->getAllTableHistory($data['table']->id);

		for($i = 0; $i < count($data['historyData']); $i++) {
			$user_name = 'Unknown User';

			if($data['historyData'][$i]->user_id) {
				$user_data = WP_User::get_data_by('id', $data['historyData'][$i]->user_id);
				$user_name = $user_data->display_name ? $user_data->display_name : $user_data->user_email;
			}
			$data['historyData'][$i]->user_name = $user_name;
			$data['historyData'][$i]->created = strtotime($data['historyData'][$i]->created);
		}

		return $data;
	}

	/**
	 * @return \SupsysticTables_Tables_Model_Tables
	 */
	private function getTablesModel()
	{
		return $this->getModelsFactory()->get('tables', 'tables');
	}

	/**
	 * @return \SupsysticTables_Tables_Model_History
	 */
	private function getHistoryModel()
	{
		return $this->getModelsFactory()->get('history', 'tables');
	}

	/**
	 * @return \SupsysticTables_Tables_Model_Conditions
	 */
	private function getConditionsModel()
	{
		return $this->getModelsFactory()->get('conditions', 'tables');
	}

	/**
	 * @return \SupsysticTables_Tables_Model_DBTables
	 */
	private function getDBTablesModel()
	{
		return $this->getModelsFactory()->get('DBTables', 'tables');
	}

	/**
	 * @return \SupsysticTables_Core_ModelsFactory
	 */
	private function getModelsFactory()
	{
		/** @var SupsysticTables_Core_Module $core */
		$core = $this->getEnvironment()->getModule('core');

		return $core->getModelsFactory();
	}

	public function getConditionsData($table) {
		if (null === $table) {
			return $table;
		}
		$conditions = array('conditions' => $this->getConditionsModel()->getConditions($table->id));
		$table->conditionsData = array_merge($conditions, $this->getConditionsParams());

		return $table;
	}

	public function additionalCloningActions($clonedTable, $newTableId) {
		$conditionModel = $this->getConditionsModel();
		$conditions = $conditionModel->getConditions($clonedTable->id);
		$conditionModel->setConditions($newTableId, $conditions);
		return $clonedTable;
	}
}
