<?php

namespace Modules\User\Services\Customer;

use App\Forkiva;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Modules\Support\Country;
use Modules\Support\GlobalStructureFilters;
use Modules\User\Enums\DefaultRole;
use Modules\User\Enums\GenderType;
use Modules\User\Models\User;

class CustomerService implements CustomerServiceInterface
{
    /** @inheritDoc */
    public function label(): string
    {
        return __("user::users.user");
    }

    /** @inheritDoc */
    public function show(int $id): User
    {
        return $this->findOrFail($id);
    }

    /** @inheritDoc */
    public function findOrFail(int $id): Builder|array|EloquentCollection|User
    {
        return $this->getModel()
            ->query()
            ->role(DefaultRole::Customer)
            ->withoutGlobalActive()
            ->findOrFail($id);
    }

    /** @inheritDoc */
    public function getModel(): User
    {
        return new ($this->model());
    }

    /** @inheritDoc */
    public function model(): string
    {
        return User::class;
    }

    /** @inheritDoc */
    public function store(array $data): User
    {
        return $this->getModel()
            ->query()
            ->create($data)
            ->assignRole(DefaultRole::Customer);
    }

    /** @inheritDoc */
    public function update(int $id, array $data): User
    {
        $user = $this->findOrFail($id);

        $exceptAttributes = [];

        if (empty($data['password'])) {
            $exceptAttributes[] = "password";
        }

        $user->update(Arr::except($data, $exceptAttributes));

        return $user;
    }

    /** @inheritDoc */
    public function destroy(int|array|string $ids): bool
    {
        return $this->getModel()
            ->query()
            ->withoutGlobalActive()
            ->role(DefaultRole::Customer)
            ->whereIn("id", parseIds($ids))
            ->delete() ?: false;
    }

    /** @inheritDoc */
    public function getStructureFilters(): array
    {
        return [
            [
                "key" => 'gender',
                "label" => __('user::customers.filters.gender'),
                "type" => 'select',
                "options" => GenderType::toArrayTrans(),
            ],
            GlobalStructureFilters::active(),
            GlobalStructureFilters::from(),
            GlobalStructureFilters::to(),
        ];
    }

    /** @inheritDoc */
    public function getFormMeta(): array
    {
        return [
            "genders" => GenderType::toArrayTrans(),
            "countries" => Country::toList()
        ];
    }

    /** @inheritDoc */
    public function search(?string $query = null): Collection
    {
        if (is_null($query)) {
            return collect();
        }

        return $this->getModel()
            ->query()
            ->role(DefaultRole::Customer)
            ->search($query)
            ->limit(5)
            ->get();
    }

    /** @inheritDoc */
    public function get(array $filters = [], ?array $sorts = []): LengthAwarePaginator
    {
        return $this->getModel()
            ->query()
            ->withoutGlobalActive()
            ->role(DefaultRole::Customer)
            ->filters($filters)
            ->sortBy($sorts)
            ->paginate(Forkiva::paginate())
            ->withQueryString();
    }
}
