<?php namespace RZtrade\Helpers;

defined('_JEXEC') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Table\Table;
use Joomla\Registry\Registry;
use Joomla\Utilities\ArrayHelper;

class ORMHelper
{

    /**
     * Префикс таблиц
     *
     * @var string
     * @since version
     *
     */
    protected static $table_prefix = 'TableRztrade';


    /**
     * Загрузка таблиц
     *
     * @since version
     */
    protected static function loadTables()
    {
        MainHelper::loadTables();
    }


    /**
     *
     * Вставить или обновить строку
     *
     * @param string $table_name - название файла таблиц
     * @param string|array $wheres - условия
     * @param array $data - данные
     *
     * @return boolean|object
     * @since version
     *
     * Примеры вызова:
     * ORMHelper::insertOrUpdate('companies', [ 'type' => 1, 'title' => 'Компания' ]);
     * ORMHelper::insertOrUpdate('companies', [ 'id' => 333, 'type' => 1, 'title' => 'Компания' ], 'id');
     * ORMHelper::insertOrUpdate('companies', [ 'id' => 333, 'status' => 3, 'type' => 1, 'title' => 'Компания' ], ['id', 'status']);
     */
    public static function insertOrUpdate($table_name, $data = [], $wheres = [])
    {
        self::loadTables();
        $table = Table::getInstance(ucfirst($table_name), self::$table_prefix);
        $wheres_for_table = [];

        if(is_string($wheres))
        {
            if(isset($data[$wheres]))
            {
                $wheres_for_table[$wheres] = $data[$wheres];
            }
        }

        if(is_array($wheres))
        {
            foreach ($wheres as $where)
            {
                if(isset($data[$where]))
                {
                    $wheres_for_table[$where] = $data[$where];
                }
            }
        }

        $table->load($wheres_for_table);
        $table->bind($data);

        if(!$table->check() || !$table->store())
        {
            return false;
        }

        return self::tableDataToObject($table);
    }


    /**
     * Только обновить строку
     *
     * @param string $table_name - название файла таблиц
     * @param string|array $wheres - условия
     * @param array $data - данные
     *
     * @return false|object
     *
     * @since version
     *
     * Примеры вызова:
     * ORMHelper::update('notifications', 'user_id', ['user_id' => 33, 'message' => 'Уведомление прочитано']);
     * ORMHelper::update('notifications', ['user_id', 'type'], ['type' => 3, 'user_id' => 33, 'message' => 'Уведомление прочитано']);
     *
     */
    public static function update($table_name, $wheres, $data = [])
    {
        self::loadTables();
        $table = Table::getInstance(ucfirst($table_name), self::$table_prefix);
        $wheres_for_table = [];

        if(is_string($wheres))
        {
            if(isset($data[$wheres]))
            {
                $wheres_for_table[$wheres] = $data[$wheres];
            }
        }

        if(is_array($wheres))
        {
            foreach ($wheres as $where)
            {
                if(isset($data[$where]))
                {
                    $wheres_for_table[$where] = $data[$where];
                }
            }
        }

        $primary_key = $table->getKeyName();
        $table->load($wheres_for_table);

        if(!isset($table->$primary_key))
        {
            return false;
        }

        $table->bind($data);

        if(!$table->check() || !$table->store())
        {
            return false;
        }

        return self::tableDataToObject($table);
    }


    /**
     * Выбрать несколько строк
     *
     * @param string $table_name - название файла таблиц
     * @param string|array $wheres - условия
     * @param array $data - данные
     * @param array|string $select - колонки для выбора
     * @param int $count - кол-во выборки
     *
     * @return array
     *
     * @since version
     *
     * Примеры вызова:
     * ORMHelper::select('companies', 'user_id', ['user_id' => 333]);
     * ORMHelper::select('companies', ['status' => 3, 'user_id'], ['user_id' => 333, 'status' => 2]);
     * ORMHelper::select('companies', ['status' => 3, 'user_id'], ['user_id' => 333, 'status' => 2], ['id', 'title']);
     * ORMHelper::select('companies', ['status' => 3, 'user_id'], ['user_id' => 333, 'status' => 2], ['id', 'title'], 100);
     *
     */
    public static function select($table_name, $wheres, $data = [], $select = '*', $count = 0)
    {
        self::loadTables();
        $table = Table::getInstance(ucfirst($table_name), self::$table_prefix);
        $wheres_for_table = [];

        if(is_string($wheres))
        {
            if(isset($data[$wheres]))
            {
                $wheres_for_table[$wheres] = $data[$wheres];
            }
        }

        if(is_array($wheres))
        {
            foreach ($wheres as $where)
            {
                if(isset($data[$where]))
                {
                    $wheres_for_table[$where] = $data[$where];
                }
            }
        }

        $table_name = $table->getTableName();
        $db = Factory::getDbo();
        $query = $db->getQuery(true);

        if(is_string($select))
        {
            if($select === '*')
            {
                $query->select('*');
            }
            else
            {
                $query->select($db->qn($table_name . '.' .  $select));
            }
        }

        if(is_array($select))
        {
            foreach ($select as $column)
            {
                $query->select($db->qn($table_name . '.' . $column));
            }
        }

        $query->from($db->qn($table_name));

        foreach ($wheres_for_table as $where_key => $where_value)
        {
            $query->where($db->qn($where_key) . ' = ' . $db->q($where_value));
        }

        if($count > 0)
        {
            $query->setLimit($count);
        }

        $list = $db->setQuery($query)->loadObjectList();

        if(!is_array($list))
        {
            $list = [];
        }

        return $list;
    }


    /**
     * Выбрать только одну строку
     *
     * @param string $table_name - название файла таблиц
     * @param string|array $wheres - условия
     * @param array $data - данные
     *
     * @return false|object
     *
     * @since version
     *
     * Примеры вызова:
     * ORMHelper::selectRow('companies', 'id', ['id' => 333]);
     * ORMHelper::selectRow('companies', ['id', 'type'], ['id' => 333, 'type' => 3]);
     *
     */
    public static function selectRow($table_name, $wheres, $data = [])
    {
        self::loadTables();
        $table = Table::getInstance(ucfirst($table_name), self::$table_prefix);
        $wheres_for_table = [];

        if(is_string($wheres))
        {
            if(isset($data[$wheres]))
            {
                $wheres_for_table[$wheres] = $data[$wheres];
            }
        }

        if(is_array($wheres))
        {
            foreach ($wheres as $where)
            {
                if(isset($data[$where]))
                {
                    $wheres_for_table[$where] = $data[$where];
                }
            }
        }

        $primary_key = $table->getKeyName();
        $table->load($wheres_for_table);

        if(!isset($table->$primary_key))
        {
            return false;
        }

        return self::tableDataToObject($table);
    }


    /**
     * Увеличение hit (стандартный джумловский hit)
     *
     * @param string $table_name - название файла таблиц
     * @param string|array $wheres - условия
     * @param array $data - данные
     *
     *
     * @return boolean
     * @since version
     *
     * Примеры вызова:
     * ORMHelper::hit('companies', 'id', ['id' => 333]);
     * ORMHelper::hit('companies', ['id', 'type'], ['id' => 333, 'type' => 3]);
     *
     */
    public static function hit($table_name, $wheres, $data)
    {
        self::loadTables();
        $table = Table::getInstance(ucfirst($table_name), self::$table_prefix);

        $wheres_for_table = [];

        if(is_string($wheres))
        {
            if(isset($data[$wheres]))
            {
                $wheres_for_table[$wheres] = $data[$wheres];
            }
        }

        if(is_array($wheres))
        {
            foreach ($wheres as $where)
            {
                if(isset($data[$where]))
                {
                    $wheres_for_table[$where] = $data[$where];
                }
            }
        }

        $table->load($wheres_for_table);

        if(empty($table->id))
        {
            self::insertOrUpdate($table_name, $data);
            $table->load($wheres_for_table);
        }

        return $table->hit();
    }


    /**
     * Получить колонки таблицы
     *
     * @param Table $table - таблица
     *
     * @return object
     *
     * @since version
     *
     */
    protected static function tableDataToObject(Table $table)
    {
        $properties = $table->getProperties(1);
        $item = ArrayHelper::toObject($properties, '\JObject');

        if (property_exists($item, 'params'))
        {
            $registry = new Registry($item->params);
            $item->params = $registry->toArray();
        }

        return $item;
    }


}