<?php

namespace App\Repositories;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

abstract class BaseRepository implements RepositoryInterface
{
    protected $model;
    protected $query;

    public function __construct(Model $model)
    {
        $this->model = $model;
        $this->query = $model->newQuery();
    }

    public function all()
    {
        return $this->query->get();
    }

    public function find($id)
    {
        return $this->query->find($id);
    }

    public function create(array $data)
    {
        return $this->model->create($data);
    }

    public function update($id, array $data)
    {
        $model = $this->find($id);
        
        if ($model) {
            $model->update($data);
            return $model;
        }

        return null;
    }

    public function delete($id)
    {
        $model = $this->find($id);
        
        if ($model) {
            return $model->delete();
        }

        return false;
    }

    public function with($relations)
    {
        if (is_array($relations)) {
            $this->query->with($relations);
        } else {
            $this->query->with($relations);
        }

        return $this;
    }

    public function where($column, $operator = null, $value = null)
    {
        if (func_num_args() === 2) {
            $this->query->where($column, $operator);
        } else {
            $this->query->where($column, $operator, $value);
        }

        return $this;
    }

    public function whereIn($column, array $values)
    {
        $this->query->whereIn($column, $values);
        return $this;
    }

    public function orderBy($column, $direction = 'asc')
    {
        $this->query->orderBy($column, $direction);
        return $this;
    }

    public function paginate($perPage = 15)
    {
        return $this->query->paginate($perPage);
    }

    public function count()
    {
        return $this->query->count();
    }

    public function exists($id)
    {
        return $this->model->where($this->model->getKeyName(), $id)->exists();
    }

    public function resetQuery()
    {
        $this->query = $this->model->newQuery();
        return $this;
    }

    public function getModel()
    {
        return $this->model;
    }

    public function getQuery()
    {
        return $this->query;
    }

    public function setQuery(Builder $query)
    {
        $this->query = $query;
        return $this;
    }
}
