<?php

namespace App\Traits;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;

trait HasFilterRequest
{

    const F_LESS_EQ_DATETIME     = 'F_LESS_EQ_DATETIME';
    const F_THAN_EQ_DATETIME     = 'F_THAN_EQ_DATETIME';
    const F_IN_DATETIME          = 'F_IN_DATETIME';
    const F_NOT_CONTAIN          = 'F_NOT_CONTAIN';
    const F_BOOLEAN              = 'F_BOOLEAN';
    const F_TEXT                 = 'F_TEXT';

    protected function F_TEXT(&$builder, string $key, Request $request)
    {
        $value = $request->get($key);
        return $builder->where(
            $key,
            'LIKE',
            "%$value%"
        );
    }

    protected function F_LESS_EQ_DATETIME(&$builder, string $key, Request $request)
    {
        $value = $request->get($key);
        $datetime = now()->setTimestamp($value);
        return $builder->where(
            $key,
            '<=',
            $datetime
        );
    }

    protected function F_THAN_EQ_DATETIME(&$builder, string $key, Request $request)
    {
        $value = $request->get($key);
        $datetime = now()->setTimestamp($value);
        return $builder->where(
            $key,
            '>=',
            $datetime
        );
    }

    protected function F_IN_DATETIME(&$builder, string $key, Request $request)
    {
        $from = $request->get($key);
        $to = $request->get($key . '_to', now()->getTimestamp());
        $fromDatetime = now()->setTimestamp($from);
        $toDatetime = now()->setTimestamp($to);
        return $builder->where(
            $key,
            '>=',
            $fromDatetime
        )->where(
            $key,
            '<=',
            $toDatetime
        );
    }

    protected function F_BOOLEAN(&$builder, string $key, Request $request)
    {
        $value = $request->get($key);
        if (is_numeric($value)) {
            $value = (int) $value;
        } else if (is_string($value)) {
            $value = $value === 'true' ? 1 : 0;
        } else {
            $value = 0;
        }

        return $builder->where(
            $key,
            '=',
            $value
        );
    }

    protected function F_NOT_CONTAIN(&$builder, string $key, Request $request)
    {
        $value = $request->get($key);
        return $builder->where(
            $key,
            '=',
            $value
        );
    }

    /**
     * Where And with filter
     *
     * @param \Illuminate\Database\Eloquent\Builder $builder
     * @param Request $request
     * @param array $filterKeys
     * ```
     * "requestKey" || "requestKey" => [type: 'F_...',column: '']
     * ```
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function filterRequest(&$builder, Request $request, array $filterKeys)
    {
        foreach ($filterKeys as $requestKey => $typeFilter) {
            $value = $request->get($requestKey);
            if (!empty($value) || $value == '0') {
                if (is_string($typeFilter)) {
                    $builder = $this->{$typeFilter}($builder, $requestKey, $request);
                }
                if (is_array($typeFilter)) {
                    $builder = $this->{$typeFilter['type']}($builder, $typeFilter['column'], new Request([
                        $typeFilter['column'] => $value
                    ]));
                }
            }
        }
        return $builder;
    }
}
