<?php

namespace Ignite\Core\Models\Grid;

use Ignite\Core\Entities\Filters\QueryPermissionFilters;
use Illuminate\Database\DatabaseManager;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Collection;
use Yajra\DataTables\DataTables;

class UserTable extends QueryTable
{
    /**
     * @var UserFormatter
     */
    protected UserFormatter $formatter;

    /**
     * UserTable constructor.
     *
     * @param DataTables $datatables
     * @param DatabaseManager $databaseManager
     * @param UserFormatter $formatter
     * @param array $params
     */
    public function __construct(
        DataTables      $datatables,
        DatabaseManager $databaseManager,
        UserFormatter   $formatter,
        array           $params = []
    ) {
        parent::__construct($datatables, $databaseManager, $params);

        $this->formatter = $formatter;
    }

    /**
     * The columns to show.
     *
     * @return array
     */
    public function columns(): array
    {
        return [
            'action' => [
                'name' => 'actions',
                'title' => 'Actions',
                'searchable' => false,
                'orderable' => false,
                'exportable' => false,
                'printable' => false,
                'visible' => true,
                'width' => '200px',
                'class' => 'actions',
            ],
            'user_id' => [
                'title' => 'User ID',
                'name' => 'user.user_id',
                'orderable' => true,
                'exportable' => true,
            ],
            'name' => [
                'title' => 'Group(s)',
                'name' => 'group_name',
                'orderable' => true,
                'exportable' => true,
                'searchable' => false,
            ],
            'first' => [
                'title' => 'First',
                'name' => 'user.first',
                'orderable' => true,
                'exportable' => true,
            ],
            'last' => [
                'title' => 'Last',
                'name' => 'user.last',
                'orderable' => true,
                'exportable' => true,
            ],
            'email' => [
                'title' => 'E-mail',
                'name' => 'user.email',
                'orderable' => true,
                'exportable' => true,
            ],
            'internal' => [
                'title' => 'Type',
                'name' => 'user.internal',
                'orderable' => true,
                'exportable' => true,
            ],
            'status' => [
                'title' => 'Status',
                'name' => 'user.status',
                'orderable' => true,
                'exportable' => true,
            ],
            'created_at' => [
                'title' => 'Created',
                'name' => 'user.created_at',
                'orderable' => true,
                'exportable' => true,
            ],
            'last_login_at' => [
                'title' => 'Last Login',
                'name' => 'user.last_login_at',
                'orderable' => true,
                'exportable' => true,
            ],
            'updated_at' => [
                'title' => 'Last Updated',
                'name' => 'user.updated_at',
                'orderable' => true,
                'exportable' => true,
            ],
        ];
    }

    /**
     * The user query.
     *
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder|Collection
     */
    public function query(): \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder|Collection
    {
        $columns = collect($this->getColumns())
            ->keyBy('name')
            ->except(['actions', 'group_name'])
            ->keys()
            ->toArray();

        $query = $this->getConnection()
            ->table('core_user as user')
            ->select($columns)
            ->addSelect($this->getConnection()->raw('GROUP_CONCAT(group.name SEPARATOR ", ") as group_name'))
            ->leftJoin('core_user_group', 'core_user_group.user_id', '=', 'user.user_id')
            ->leftJoin('core_group as group', 'core_user_group.group_id', '=', 'group.id')
            ->groupBy('user.user_id');

        return QueryPermissionFilters::for('core.user.browse')
            ->apply($query, 'user');
    }

    /**
     * Get a map of column keys => functions to format columns.
     *
     * @return array
     */
    protected function getColumnFormattingMap(): array
    {
        return [
            'action' => function ($model) { return $this->formatter->actions($model); },
            'name' => function ($model) { return $this->formatter->group($model); },
            'first' => function ($model) { return $this->formatter->first($model); },
            'last' => function ($model) { return $this->formatter->last($model); },
            'email' => function ($model) { return $this->formatter->email($model); },
            'internal' => function ($model) { return $this->formatter->type($model); },
            'status' => function ($model) { return $this->formatter->status($model); },
            'created_at' => function ($model) { return $this->formatter->createdAt($model); },
            'updated_at' => function ($model) { return $this->formatter->updatedAt($model); },
            'last_login_at' => function ($model) { return $this->formatter->lastLoginAt($model); },
        ];
    }

    /**
     * Get default builder parameters.
     *
     * @return array
     */
    protected function getBuilderParameters(): array
    {
        return parent::getBuilderParameters([
            'order' => [
                [2, 'asc'] // Name
            ],
        ]);
    }
}
