<?php
namespace App\Lib;
use Carbon\Carbon;
use Illuminate\Validation\ValidationException;
class Searchable{
    public function searchable(){
        return function($params, $like = true) {
            $search = request()->search;
            if (!$search) {
                return $this;
            }

            if (!is_array($params)) {
                throw new \Exception("Search parameters should be an array");
            }

            $search = $like ? "%$search%" : $search;
            $this->where(function ($q) use ($params, $search) {
                foreach ($params as $param) {
                    $relationData = explode(':', $param);
                    if (isset($relationData[1])) {
                        foreach (explode(',', $relationData[1]) as $column) {
                            if(!$relationData[0]){
                                continue;
                            }
                            $q->orWhereHas($relationData[0], function ($q) use ($column, $search) {
                                $q->where($column, 'like', $search);
                            });
                        }
                    } else {
                        $column = $param;
                        $q->orWhere($column, 'LIKE', $search);
                    }
                }
            });
            return $this;
        };
    }
    public function filter() {
        return function($params){

            if (!is_array($params)) {
                throw new \Exception("Search parameters should be an array");
            }

            foreach ($params as $param) {
                $relationData = explode(':', $param);
                $filters = array_keys(request()->all());
                if (isset($relationData[1])) {
                    foreach (explode(',', $relationData[1]) as $column) {
                        if (request()->$column != null) {
                            $this->whereHas($relationData[0],function($q) use ($column, $relationData){
                                $q->where($column,request()->$column);
                            });
                        }
                    }
                }else{
                    $column = $param;
                    if (in_array($column, $filters) && request()->$column != null) {
                        if(gettype(request()->$column) =='array'){
                            $this->whereIn($column, request()->$column);
                        }else{
                            $this->where($column, request()->$column);
                        }
                    }
                }
            }
            return $this;
        };
    }
    public function dateFilter(){
        return function($column = 'created_at'){
            if (!request()->date) {
                return $this;
            }
            try{
                $date      = explode('-', request()->date);
                $startDate = Carbon::parse(trim($date[0]))->format('Y-m-d');
                $endDate = isset($date[1]) ? Carbon::parse(trim($date[1]))->format('Y-m-d') : $startDate;
            }catch(\Exception $e){
                throw ValidationException::withMessages(['error' => 'Invalid date format']);
            }
            return $this->whereDate($column, '>=', $startDate)->whereDate($column, '<=', $endDate);
        };
    }
}
