<?php

namespace App\Packages\Follower\Repository;

use App\Packages\Core\Repository\AbstractRepository;
use App\Packages\Follower\Models\FollowerRelation;
use App\Packages\User\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;

/**
 * Class FollowerRepository
 * @package App\Packages\Follower\Repository
 *
 * @property FollowerRelation $model
 */
class FollowerRepository extends AbstractRepository
{
    const LIMIT_PAGE = 20;

    public static function init()
    {
        return new FollowerRepository(FollowerRelation::class);
    }

    /**
     * @return Builder
     */
    public function baseActiveRelations()
    {
        return $this->query()->where('status', true);
    }

    public function getFollowerRow($user, $follower)
    {
        return $this->query()
            ->where('user_id', $user->id)
            ->where('follower_id', $follower->id)
            ->first();
    }

    /**
     * @param $user
     * @param $follower
     * @return Builder|FollowerRelation|object|null
     */
    public function getActiveFollowerRow($user, $follower)
    {
        return $this->baseActiveRelations()
            ->where('user_id', $user->id)
            ->where('follower_id', $follower->id)
            ->first();
    }

    /**
     * @param User $user
     * @param User $follower
     * @return bool
     */
    public function isFollower($user, $follower)
    {
        $check = $this->getActiveFollowerRow($user, $follower);

        return (bool) $check;
    }

    /**
     * @param User $user
     * @param User $following
     * @return bool
     */
    public function isFollowing($user, $following)
    {
        $check = $this->getActiveFollowerRow($following, $user);

        return (bool) $check;
    }

    /**
     * @param User $user
     * @return int
     */
    public function countUserFollowers($user)
    {
        return $this->baseActiveRelations()
            ->where('user_id', $user->id)
            ->count();
    }

    /**
     * @param User $user
     * @return int
     */
    public function countUserFollowing($user)
    {
        return $this->baseActiveRelations()
            ->where('follower_id', $user->id)
            ->count();
    }


    /**
     * @param User $user
     * @param array $params
     * @return Builder
     */
    public function baseUserFollowers($user, $params = [])
    {
        $query = $this->baseActiveRelations()
            ->leftJoin(
                'table_user as user',
                'user.id',
                '=',
                'table_follower_relation.follower_id'
            )
            ->where('table_follower_relation.user_id', $user->id);

        if ( isset($params['nickname']) && ! empty($params['nickname']) ) {
            $nickname = mb_strtolower($params['nickname']);
            $query->whereRaw("LOWER(user.nickname) LIKE ?", ["{$nickname}%"]);
        }

        return $query;
    }

    /**
     * @param User $user
     * @param array $params
     * @return Builder
     */
    public function baseUserFollowing($user, $params = [])
    {
        $query = $this->baseActiveRelations()
            ->leftJoin(
                'table_user as user',
                'user.id',
                '=',
                'table_follower_relation.user_id'
            )
            ->where('table_follower_relation.follower_id', $user->id);

        if ( isset($params['nickname']) && ! empty($params['nickname']) ) {
            $nickname = mb_strtolower($params['nickname']);
            $query->whereRaw("LOWER(user.nickname) LIKE ?", ["{$nickname}%"]);
        }

        return $query;
    }

    /**
     * @param User $user
     * @param string $search
     * @param int $page
     * @return Builder[]|Collection
     */
    public function getPaginatedUserFollowers($user, $search = '', $page = 1)
    {
        $query = $this->baseUserFollowers(
            $user,
            [
                'nickname' => $search
            ]
        )
        ->select('user.*')
        ->orderBy('user.nickname', 'DESC');

        $query->skip(($page - 1) * static::LIMIT_PAGE)->take(static::LIMIT_PAGE);

        return $query->get();
    }

    /**
     * @param User $user
     * @param string $search
     * @param int $page
     * @return Builder[]|Collection
     */
    public function getPaginatedUserFollowing($user, $search = '', $page = 1)
    {
        $query = $this->baseUserFollowing(
            $user,
            [
                'nickname' => $search
            ]
        )
        ->select('user.*')
        ->orderBy('user.nickname', 'DESC');

        $query->skip(($page - 1) * static::LIMIT_PAGE)->take(static::LIMIT_PAGE);

        return $query->get();
    }

    /**
     * @param User $user
     * @param string $search
     * @return int
     */
    public function countPaginatedUserFollowers($user, $search = '')
    {
        return $this->baseUserFollowers(
            $user,
            [
                'nickname' => $search
            ]
        )
        ->count();
    }

    /**
     * @param User $user
     * @param string $search
     * @return int
     */
    public function countPaginatedUserFollowing($user, $search = '')
    {
        return $this->baseUserFollowing(
            $user,
            [
                'nickname' => $search
            ]
        )
        ->count();
    }


}
