<?php

namespace App\Traits;

use Illuminate\Http\Request;

trait IsDatatableRequest
{
    const DATATABLE_DATETIME = 'datetime';
    const DATATABLE_STRING = 'string';
    const DATATABLE_NUMBER = 'number';
    const DATATABLE_OBJECT = 'object';
    const DATATABLE_ARRAY = 'array';
    const DATATABLE_CHILD = 'child';
    const DATATABLE_STATUS = 'status';
    const DATATABLE_ACTION = 'action';
    const DATATABLE_CENTER = 'dt-head-center';
    const DATATABLE_DETAIL_CONTROL = 'detail_control';

    protected function _columns()
    {
        return [
            [
                'label' => 'Label',
                'name' => 'column',
                'type' => 'DATATABLE_...', // nullable
                'orderable' => true, // nullable
                'className' => 'dt-head-center', // nullable
                'visible' => true
            ]
        ];
    }

    /**
     * @return array
     */
    public function paginateWithDatatable(&$builder, Request $request)
    {
        $columns = $this->_columns();
        $perPage = $request->input('length');
        $page = ((int) $request->input('start', 0) / (int) $request->input('length', 1)) + 1;

        // order by
        if ($request->get('order')) {
            $orders = $request->get('order');
            if (is_array($orders)) {
                foreach ($orders as $index => $order) {
                    $indexCol   = (int) $order['column']; // number
                    $dir = $order['dir']; // asc|desc
                    $builder = $builder->orderBy(
                        $columns[$indexCol]['name'], // get name by columns
                        $dir
                    );
                }
            }
        }

        $paginate =  $builder->paginate(
            perPage: $perPage,
            page: $page
        );

        return [
            "recordsTotal" => $paginate->total(),
            "recordsFiltered" => $paginate->total(),
            "payload" => $request->all(),
            "data" => $paginate->getCollection()->map(function ($record)  use ($columns) {
                $data = collect($columns)
                    ->values()
                    ->map(function ($column) use ($record) {
                        return $record->{$column['name']};
                    });
                return $data;
            })->toArray()
        ];
    }
}
