<?php

namespace App\PackagesApi\v4\Controllers\Search;

use App\Http\Controllers\Controller;
use App\Packages\User\Models\User;
use App\Packages\v4\Capsule\Repository\CapsuleRepository;
use App\Packages\v4\Capsule\Transformer\CapsuleArrayTransformer;
use App\Packages\v4\User\Repository\UserRepository;
use App\Packages\v4\User\Transformer\UserTransformer;
use App\PackagesApi\v4\Requests\Search\SearchRequest;
use \Illuminate\Http\JsonResponse;

/**
 * Class SearchController
 * @package App\PackagesApi\Controllers\Search
 */
class SearchController extends Controller {

    private $limit = 10;
    private $offset = 0;

    /** @var User  */
    private $auth;

    public function __construct()
    {
        $this->auth = user();
    }

    /**
     * @param SearchRequest $request
     * @return JsonResponse
     */
    public function onlyUsers(SearchRequest $request)
    {
        $this->auth->saveAccess('View search page users');

        if ($request->has('limit') && $request->filled('limit')) {
            $this->limit = $request->limit;
        }

        if ($request->has('offset') && $request->filled('offset')) {
            $this->offset = $request->offset;
        }

        if ($request->filled('keyword')) {
            $usersCount = UserRepository::init()->countSearchUsersByKeyword($this->auth->id, $request->keyword, $this->offset);
            $users = UserRepository::init()->getSearchUsersByKeyword($this->auth->id, $request->keyword, $this->limit, $this->offset);

            $users = $users->map(
                function ($user) {
                    return UserTransformer::searchResult($user, $this->auth);
                }
            );

            $currentCount = $users->count();
            $left = $usersCount - $currentCount;

            return jsonSuccess([
                'count' => $currentCount,
                'users' => $users,
                'has_more' => ($left > 0) ? true : false,
            ]);
        } else {
            $recent = UserRepository::init()->getLastSearches($this->auth->id, 5);
            $ignore = $recent->pluck('id');

            if ($this->offset == 0) {
                $recent = $recent->map(
                    function ($user) {
                        return UserTransformer::searchResult($user, $this->auth);
                    }
                );

                $this->limit -= $recent->count();
            } else {
                $recent = collect();
            }

            $suggestedCount = UserRepository::init()->countSuggestedAndPopularUsersForSearch($this->auth->id, $ignore, $this->offset);
            $suggested = UserRepository::init()->getSuggestedAndPopularUsersForSearch($this->auth->id, $ignore, $this->limit, $this->offset);

            $suggested = $suggested->map(
                function ($user) {
                    return UserTransformer::searchResult($user, $this->auth);
                }
            );

            $currentCount = $suggested->count();
            $left = $suggestedCount - $currentCount;

            return jsonSuccess([
                'recent' => $recent,
                'suggested' => $suggested,
                'has_more' => ($left > 0) ? true : false,
            ]);
        }
    }

    /**
     * @param SearchRequest $request
     * @return JsonResponse
     */
    public function onlyCapsules(SearchRequest $request)
    {
        $this->auth->saveAccess('View search page capsules');

        if ($request->has('limit') && $request->filled('limit')) {
            $this->limit = $request->limit;
        }

        if ($request->has('offset') && $request->filled('offset')) {
            $this->offset = $request->offset;
        }

        if ($request->filled('keyword')) {
            return jsonSuccess([
                'message' => 'Not yet implemented'
            ]);
        } else {

            $recent = collect();
            $ignore = [];

            if ($this->offset == 0) {
                $this->limit -= $recent->count();
            }

            $suggestedCount = CapsuleRepository::init()->countSuggestedCapsulesForSearch($this->auth, $ignore, $this->offset);
            $suggested = CapsuleRepository::init()->getSuggestedCapsulesForSearch($this->auth, $ignore, $this->limit, $this->offset);

            $suggested = $suggested->map(
                function ($capsule) {
                    return CapsuleArrayTransformer::searchObject($capsule);
                }
            );

            $currentCount = $suggested->count();
            $left = $suggestedCount - $currentCount;

            return jsonSuccess([
                'recent' => $recent,
                'suggested' => $suggested,
                'has_more' => ($left > 0) ? true : false,
            ]);
        }
    }

    /**
     * @param SearchRequest $request
     * @return JsonResponse
     */
    public function searchAll(SearchRequest $request)
    {
        $this->auth->saveAccess('View search page');

        if ($request->filled('keyword')) {
            $users = UserRepository::init()->getSearchUsersByKeyword($this->auth->id, $request->keyword, $this->limit);

            $users = $users->map(
                function ($user) {
                    return UserTransformer::searchResult($user, $this->auth);
                }
            );

            $usersCount = $users->count();

            return jsonSuccess([
                'count' => $usersCount,
                'users' => $users
            ]);
        } else {

            $recent = UserRepository::init()->getLastSearches($this->auth->id, 5);
            $ignore = $recent->pluck('id');
            $recent = $recent->map(
                function ($user) {
                    return UserTransformer::searchResult($user, $this->auth);
                }
            );

            $this->limit -= $recent->count();

            $suggested = collect();

            $adminSuggested = UserRepository::init()->getSuggestedUsersForSearch($this->auth->id, $ignore, $this->limit);
            $suggested = $suggested->merge($adminSuggested);

            $this->limit -= $suggested->count();

            if ($this->limit > 0) {
                $popularSuggested = UserRepository::init()->getPopularUsersForSearch($this->auth->id, $ignore, $this->limit);
                $suggested = $suggested->merge($popularSuggested);
            }

            $suggested = $suggested->map(
                function ($user) {
                    return UserTransformer::searchResult($user, $this->auth);
                }
            );

            return jsonSuccess([
                'recent' => $recent,
                'suggested' => $suggested
            ]);
        }
    }

}
