<?php

namespace TdyCommons\Table;

use TdyCommons\Model\BaseOption;
use AevWorkflows\Model;
use Zend\Db\Adapter\Adapter as DatabaseAdapter;
use Zend\Db\ResultSet\HydratingResultSet;
use Zend\Db\Sql\Sql;
use Zend\Db\Sql\Predicate;
use Zend\Db\Sql\Select;
use Zend\Db\Sql\Where;
use Zend\Paginator\Adapter\DbSelect;
use Zend\Paginator\Paginator;

/**
 * Class BaseOptions
 * @package TdyCommons\Table
 *
 * @author  James Lloyd Atwil <james@nadows.com>
 */
class BaseOptions
{
    /**
     * @var DatabaseAdapter
     */
    protected $adapter;

    /**
     * Selection slug.
     *
     * @var string
     */
    protected $selectionSlug;

    /**
     * @var BaseOption
     */
    protected $objectPrototype;

    /**
     * @param DatabaseAdapter $adapter
     * @param                 $selectionSlug
     * @param BaseOption      $objectPrototype
     */
    public function __construct(DatabaseAdapter $adapter, $selectionSlug, BaseOption $objectPrototype)
    {
        $this->adapter         = $adapter;
        $this->selectionSlug   = $selectionSlug;
        $this->objectPrototype = $objectPrototype;
    }

    /**
     * @param string $q
     * @param array  $sort
     * @param bool   $paginated
     *
     * @return bool|HydratingResultSet|Paginator
     */
    public function fetch($q = '', $sort = array(), $paginated = false)
    {
        $select = new Select();
        $select->from(array('so' => TBL_COMMONS_SELECTIONS_OPTIONS));
        $select->join(array('ss' => TBL_COMMONS_SELECTIONS), 'ss.id = so.selection_id', array('selection_slug' => 'slug'), Select::JOIN_LEFT);
        $select->columns(array('so' => Select::SQL_STAR));
        $conditions = array();

        $where = new Where(array());
        $where->addPredicate(new Predicate\Expression('ss.slug = ?', $this->selectionSlug));
        $where->addPredicate(new Predicate\Expression('so.is_active = 1'));
        $conditions[] = $where;

        if (!empty($q)) {
            $where = new Where(array(), Predicate\PredicateSet::OP_OR);
            $where->addPredicate(new Predicate\Like('so.name', '%' . $q . '%'));
            $conditions[] = $where;
        }

        $select->where($conditions, Predicate\PredicateSet::OP_AND);

        if (empty($sort)) {
            $select->order('so.ordinal ASC');
        } else {
            $select->order($sort);
        }

        $resultSet = new HydratingResultSet();
        $resultSet->setObjectPrototype($this->objectPrototype);

        if ($paginated) {
            $paginatorAdapter = new DbSelect($select, $this->adapter, $resultSet);
            $paginator        = new Paginator($paginatorAdapter);

            return $paginator;
        } else {
            $sql       = new Sql($this->adapter);
            $statement = $sql->prepareStatementForSqlObject($select);
            $results   = $statement->execute();

            $resultSet->initialize($results);

            if (!$resultSet) {
                return false;
            } else {
                return $resultSet;
            }
        }
    }

    /**
     * @param $id
     *
     * @return Model\Scope|bool
     */
    public function get($id)
    {
        $select = new Select();
        $select->from(array('so' => TBL_COMMONS_SELECTIONS_OPTIONS));
        $select->join(array('ss' => TBL_COMMONS_SELECTIONS), 'ss.id = so.selection_id', array('selection_slug' => 'slug'), Select::JOIN_LEFT);
        $select->columns(array('so' => Select::SQL_STAR));
        $conditions = array();

        $where = new Where(array());
        $where->addPredicate(new Predicate\Expression('ss.slug = ?', $this->selectionSlug));
        $where->addPredicate(new Predicate\Expression('so.value = ?', (string) $id));
        $where->addPredicate(new Predicate\Expression('so.is_active = ?', 1));
        $conditions[] = $where;

        $select->where($conditions, Predicate\PredicateSet::OP_AND);

        $resultSet = new HydratingResultSet();
        $resultSet->setObjectPrototype($this->objectPrototype);

        $sql       = new Sql($this->adapter);
        $statement = $sql->prepareStatementForSqlObject($select);
        $results   = $statement->execute();

        $resultSet->initialize($results);

        $row = $resultSet->current();
        if (!$row) {
            return false;
        } else {
            return $row;
        }
    }

}
