<?php

namespace Luticate\Utils;

abstract class LuDataAccess {
    /**
     * @param $data LuModel[]
     * @return LuDbo[]
     */
    protected static function arrayToDbo($data)
    {
        $tab = [];
        foreach ($data as $q) {
            if (!is_null($q)) {
                $tab[] = $q->toDbo();
            }
        }
        return $tab;
    }

    /**
     * @param $id int
     * @return LuModel
     */
    protected static function _getModelById($id)
    {
        return static::getModel()->where('id', '=', $id)->first();
    }

    /**
     * @param $id int
     * @return LuDbo|null
     */
    public static function getById($id)
    {
        $data = self::_getModelById($id);
        if (is_null($data))
            return null;
        return $data->toDbo();
    }

    /**
     * @param $id int
     * @return bool
     */
    public static function deleteById($id)
    {
        $data = self::_getModelById($id);
        if (is_null($data))
            return false;
        $data->delete();
        return true;
    }

    /**
     * @param $data LuDbo
     * @return int
     */
    public static function addId($data)
    {
        $data = static::getModel()->fromDBO($data);
        unset($data->id);
        $data->save();
        return $data->id;
    }

    /**
     * @param $data LuDbo
     */
    public static function add($data)
    {
        $data = static::getModel()->fromDBO($data);
        $data->save();
    }

    /**
     * @param $id int
     * @param $data LuDbo
     * @return LuDbo|null
     */
    public static function editById($id, $data)
    {
        return static::getModel()->fromDBO($data, self::_getModelById($id))->save();
    }

    /**
     * @param $predicates array
     * @param $orders array
     * @param int $page
     * @param int $perPage
     * @return LuMultipleDbo
     */
    public static function getMultiple($predicates, $orders, $page = 0, $perPage = PHP_INT_MAX)
    {
        $model = static::getModel();
        foreach($predicates as $predicate) {
            $model = $model->where($predicate[0], $predicate[1], $predicate[2]);
        }
        $count = $model->count();
        foreach($orders as $order) {
            $model = $model->orderBy($order[0], $order[1]);
        }
        $data = $model->take($perPage)->offset($page * $perPage)->get();
        $dbo = self::arrayToDbo($data);

        return new LuMultipleDbo($count, $dbo);
    }

    /**
     * @return LuModel
     */
    protected static function getModel()
    {
        return null;
    }

    /**
     * @return array
     */
    protected static function getOrderBy()
    {
        return array();
    }

    public static function getAll($page = 0, $perPage = PHP_INT_MAX)
    {
        return self::getMultiple(array(), static::getOrderBy(), $page, $perPage);
    }
}