<?php

namespace App\Packages\Capsule\Repository;

use App\Packages\Capsule\Models\Capsule;
use App\Packages\Core\Repository\AbstractRepository;
use App\Packages\User\Models\User;
use Carbon\Carbon;
use DB;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Collection;

/**
 * Class CapsuleRepository
 * @package App\Packages\Capsule\Repository
 *
 * @method Capsule firstById($id)
 *
 * @property Capsule $model
 */
class CapsuleRepository extends AbstractRepository
{
    const LIMIT_READY_TO_HATCH = 100;

    public static function init()
    {
        return new CapsuleRepository(Capsule::class);
    }

    /**
     * @TODO: Is in use ???
     *
     * @param User $user
     *
     * @return Collection|Capsule[]
     */
    public function getUserPublicCapsules(User $user)
    {
        $query = $this->query()
            ->where('user_id', '=', $user->id)
            ->where('is_private', '=', false)
            ->where('is_complete', '=', true);

        return $query->get();
    }

    /**
     * @param User $user
     *
     * @return Collection|Capsule[]
     */
    public function getCapsulesLikesByUser(User $user)
    {
        $query = $this->query()
            ->leftJoin('table_capsule_like as like', 'like.capsule_id', 'table_capsule.id')
            ->where('like.user_id', '=', $user->id);

        return $query->get();
    }

    /**
     * @param User $user
     *
     * @return Collection|Capsule[]
     */
    public function getCapsulesCommentedByUser(User $user)
    {
        $query = $this->query()
            ->leftJoin('table_capsule_comment as comment', 'comment.capsule_id', 'table_capsule.id')
            ->where('comment.user_id', '=', $user->id);

        return $query->get();
    }

    /**
     * @param User $user
     *
     * @return Collection|Capsule[]
     */
    public function getCapsulesSubscribedByUser(User $user)
    {
        $query = $this->query()
            ->leftJoin('table_capsule_subscriber as subscriber', 'subscriber.capsule_id', 'table_capsule.id')
            ->where('subscriber.user_id', '=', $user->id);

        return $query->get();
    }

    /**
     * @TODO: Move to test service
     *
     * @param User $user
     *
     * @return Collection|Capsule[]
     */
    public function getUserAllCompleteCapsules(User $user)
    {
        $query = $this->query()
            ->where('user_id', '=', $user->id)
            ->where('is_complete', '=', true);

        return $query->get();
    }

    /**
     * @param User $user
     *
     * @return int
     */
    public function countUserCompleteCapsules(User $user)
    {
        return $this->query()
            ->where('user_id', '=', $user->id)
            ->where('is_complete', '=', true)
            ->count('id');
    }

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

    /**
     * @return Collection|static[]|Capsule[]
     */
    public function oldUnCompleteCapsules()
    {
        return $this->query()
            ->where('is_complete', '=', false)
            ->where('created_at', '<', now()->subDay())
            ->get();
    }

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

    /**
     * @param Carbon $date
     *
     * @return Collection|Capsule[]
     */
    public function readyToHatch(Carbon $date)
    {
        return $this->query()
            ->where('status', '=', [Capsule::STATUS_LOCKED])
            ->where('open_at', '<=', $date)
            ->where('is_complete', '=', 1)
            ->limit(static::LIMIT_READY_TO_HATCH)
            ->get();
    }

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

        return $this->query()
            ->where('is_complete', true)
            ->where('blocked', false)
            ->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(Carbon $from, Carbon $to)
    {
        $from = $from->format('Y-m-d');
        $to = $to->format('Y-m-d');

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

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