<?php
/**
 * Created by PhpStorm.
 * User: crose
 * Date: 6/21/19
 * Time: 2:02 PM
 */

namespace IMATHUZH\Qfq\Core\Report;


use IMATHUZH\Qfq\Core\Database\Database;
use IMATHUZH\Qfq\Core\Helper\OnString;
use IMATHUZH\Qfq\Core\Store\Store;

/**
 * Class Tablesorter
 * @package IMATHUZH\Qfq\Core\Report
 */
class Tablesorter {

    /**
     * @var Link
     */
    private $link = null;

    /**
     * @var Database
     */
    private $db = null;

    /**
     * Tablesorter constructor.
     *
     * @param $dbIndex
     * @throws \CodeException
     * @throws \DbException
     * @throws \UserFormException
     * @throws \UserReportException
     */
    public function __construct($dbIndex) {

        $this->link = new Link(Store::getSipInstance(), $dbIndex);

        $this->db = new Database($dbIndex);
    }

    /**
     * Create a string to be inserted in a HTML table tag.
     *
     * @param string $token - 'uniqueName' of  "{{ '<uniqueName>' AS _tablesorter-view-saver }}". With or without quotes.
     * @param string $foundInStore - will be returned
     * @return string
     * @throws \CodeException
     * @throws \DbException
     * @throws \UserFormException
     * @throws \UserReportException
     */
    public function inlineTablesorterView($token, &$foundInStore, $frCmd = '') {

        $token = OnString::trimQuote($token);
        if (empty($token)) {
            throw new \UserReportException('Missing \'uniqueName\' for "' . TABLESORTER_VIEW_SAVER . '"', ERROR_MISSING_VALUE);
        }

        // Check for forbidden characters
        if (strpos($token, ' ') !== false) {
            throw new \UserReportException('\uniqueName\` may not contain space " for' . TABLESORTER_VIEW_SAVER . '"', ERROR_INVALID_VALUE);
        }

        $foundInStore = TOKEN_FOUND_STOP_REPLACE;

        $feUser = $this->getFeUser();
        $s = $this->link->renderLink('U:' . SETTING_TABLESORTER_TABLE_ID . '=' . $token . '&' . SETTING_TABLESORTER_FE_USER . '=' . $feUser . '|s|r:8');

        $view = $this->getTableViewAsJson($token, $feUser);
        // Improve twig compatibility with escaped double quotes
        if ($frCmd === TOKEN_SQL) {
            $view = addslashes($view);
        }

        // data-tablesorter-sip='badcaffee1234' data-tablesorter-view='....'
        return "data-tablesorter-id='" . $token . "' " . DATA_TABLESORTER_SIP . "='" . $s . "' " . DATA_TABLESORTER_VIEW . "='" . $view . "' ";
    }

    /**
     * Return current FeUser or QFQ Cookie if none is logged in.
     *
     * @return array|string
     * @throws \CodeException
     * @throws \UserFormException
     */
    private function getFeUser() {
        $feUser = Store::getVar(TYPO3_FE_USER, STORE_TYPO3 . STORE_EMPTY);
        if ($feUser == '') {
            // In case there is no FE User, just take the QFQ cookie as feUserId. It only helps for the current browser session.
            $feUser = $_COOKIE[SESSION_NAME] ?? 'fake';
        }

        return $feUser;
    }

    /**
     * Retrieve all views for a given table with $tableId and views are public or assigned to user $feUser.
     *
     * @param $tableId
     * @param $feUser
     * @return string
     * @throws \CodeException
     * @throws \DbException
     * @throws \UserFormException
     */
    private function getTableViewAsJson($tableId, $feUser) {

        // Sort list by public, name
        $tablesorterViews = $this->db->sql("SELECT `sett`.`name`, `sett`.`public`, `sett`.`tableId`, `sett`.`view` FROM `" . SETTING_TABLE_NAME .
            "` AS sett WHERE `type`=? AND `tableId`=? AND ((!`public` AND `feUser`=?) OR `public`) ORDER BY `sett`.`public` DESC, `sett`.`name`, `sett`.`id`",
            ROW_REGULAR, [SETTING_TYPE_TABLESORTER, $tableId, $feUser]);

        foreach ($tablesorterViews as $key => $row) {
            // Convert mysql boolean 0/1 to json true/false (not a string!).
            $tablesorterViews[$key]['public'] = (bool)$tablesorterViews[$key]['public'];
        }

        return json_encode($tablesorterViews);
    }
}