<?php

namespace App\Packages\User\Repository;

use App\Packages\Core\Repository\AbstractRepository;
use App\Packages\User\Models\User;
use Carbon\Carbon;
use DB;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Support\Collection;

/**
 * Class UserRepository
 * @package App\Packages\User\Repository
 *
 * @method User firstById($id)
 *
 * @property User $model
 */
class UserRepository extends AbstractRepository
{
    public static function init()
    {
        return new UserRepository(User::class);
    }

	/**
     * @return Collection|User[]
     */
    public function getRegisteredUsers()
    {
        return $this->query()
            ->where('is_registered', 1)
            ->get();
    }

    /**
     * @param $phoneCode
     * @param $phoneNumber
     *
     * @return object|User|null
     */
    public function firstRegisteredByPhoneNumber($phoneCode, $phoneNumber)
    {
        return $this->query()
            ->where('phone_code', '=', $phoneCode)
            ->where('phone_number', '=', $phoneNumber)
            ->where('is_registered', '=', true)
            ->first();
    }

	/**
	 * @param string $nickname
	 *
	 * @return User|null|object
	 */
	public function findByNickname($nickname)
	{
		return $this->query()
            ->where('nickname', 'ilike', '%' . $nickname . '%')->first();
	}

	/**
	 * @param $email
	 *
	 * @return User|null|object
	 */
	public function firstByEmail($email)
	{
		return $this->query()
			->where('email', '=', $email)
			->first();
	}

	/**
	 * @param $uuid
	 *
	 * @return User|null|object
	 */
	public function firstByUuid($uuid)
	{
		return $this->query()
			->where('uuid', '=', $uuid)
			->first();
	}

    /**
     * @param $phoneHash
     *
     * @return User|null|object
     */
    public function firstByPhoneHash($phoneHash)
    {
        return $this->query()
            ->where('phone_hash', '=', $phoneHash)
            ->first();
    }

    /**
     * @return Collection|static[]|User[]
     */
    public function trashedUsers()
    {
        return $this->query()
            ->onlyTrashed()
            ->get();
    }

    /**
     * @param Carbon $date
     *
     * @return int
     */
    public function countByMonth($date)
    {
        $year = $date->format('Y');
        $month = $date->format('m');

        return $this->query()
            ->where('is_registered', true)
            ->whereRaw("date_part('year', created_at) = '{$year}' AND date_part('month', created_at) = '{$month}'")
            ->count();
    }

    /**
     * @param Carbon $from
     * @param Carbon $to
     *
     * @return int
     */
    public function countByDateRange($from, $to)
    {
        $from = $from->format('Y-m-d');
        $to = $to->format('Y-m-d');

        return $this->query()
            ->where('is_registered', true)
            ->whereRaw("created_at between '{$from}' AND '{$to}'")
            ->count();
    }

    /**
     * @param User $ownerUser
     * @param array $phoneHashes
     *
     * @return Collection
     */
    public function getContactsSyncOnTheFly(User $ownerUser, $phoneHashes)
    {
        $query = DB::table('table_user')
            ->select([
                'table_user.uuid',
                'table_user.nickname',
                'table_user.phone_code',
                'table_user.phone_number',
                'table_user.phone_hash',
                'table_user.is_registered',
                'table_user_avatar.aws_key as awsKey',

                'invite.id as isInvited',
                'friend.id as isFriend',
            ])

            ->leftJoin('table_user_avatar', 'table_user_avatar.id', '=', 'table_user.avatar_id')

            ->leftJoin('table_friend_invite as invite', function(JoinClause $join) use ($ownerUser) {
                $join
                    ->on('invite.friend_id', '=', 'table_user.id')
                    ->on('invite.user_id', '=', DB::raw($ownerUser->id));
            })

            ->leftJoin('table_friend_relation as friend', function(JoinClause $join) use ($ownerUser) {
                $join
                    ->on('friend.friend_id', '=', 'table_user.id')
                    ->on('friend.user_id', '=', DB::raw($ownerUser->id));
            })

            ->where('table_user.phone_number', '!=', $ownerUser->phone_number)
            ->whereNull('table_user.deleted_at')
            ->whereIn( 'table_user.phone_hash', $phoneHashes);

        return $query->get();
    }
}
