<?php

namespace App\Models;

use App\Domain\Feeds\Models\Feed;
use App\Domain\Votes\Models\Vote;
use Spatie\MediaLibrary\HasMedia;
use App\Domain\Points\Models\Point;
use Illuminate\Auth\Authenticatable;
use Illuminate\Support\Facades\Hash;
use Spatie\Permission\Traits\HasRoles;
use App\Domain\Users\Models\UserPackage;
use Illuminate\Notifications\Notifiable;
use App\Domain\Messenger\Models\ChatRoom;
use App\Domain\Payments\Models\Withdrawal;
use Spatie\MediaLibrary\InteractsWithMedia;
use App\Domain\Users\Observers\UserObserver;
use Spatie\Permission\Traits\HasPermissions;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Domain\Payments\Models\BankRequisites;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use App\Domain\Subscriptions\Models\Subscription;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
use App\Domain\PaymentGateway\Models\PaymentGatewayOrder;
use App\Domain\Subscriptions\Service\SubscriptionService;
use Illuminate\Auth\MustVerifyEmail as AuthMustVerifyEmail;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Auth\Passwords\CanResetPassword;

// , MustVerifyEmail
class User extends Model implements AuthenticatableContract, AuthorizableContract, MustVerifyEmail, HasMedia, CanResetPasswordContract
{
    // , AuthMustVerifyEmail
    use SoftDeletes, Authenticatable, Authorizable, HasRoles, HasPermissions, Notifiable, AuthMustVerifyEmail, InteractsWithMedia, CanResetPassword;

    const CHECKTIMEUSER = 20;
    const PAGINATE = 20;

    protected $casts = [
        'private' => 'boolean',
        'autosubscription_site' => 'boolean',
        // 'allow_adult_content' => 'boolean',
        'phone_verified' => 'boolean',
        'passport_verified' => 'boolean',
        'phone_verify_token_expire' => 'datetime',
    ];

    protected static function boot()
    {
        parent::boot();

        self::observe(UserObserver::class);
    }

    public static function system()
    {
        return User::where('username', 'inner_systemuser_api')->first();
    }

    public function withdrawals()
    {
        return $this->hasMany(Withdrawal::class);
    }

    public function bank_requisites()
    {
        return $this->hasMany(BankRequisites::class);
    }

    public function points()
    {
        return $this->hasMany(Point::class);
    }

    public function payments_orders()
    {
        return $this->hasMany(PaymentGatewayOrder::class);
    }

    public function live_feeds()
    {
        // return $this->belongsToMany(Feed::class, 'users_live_feeds')
        // ->withPivot('times')->orderByPivot('times', 'desc');

        return $this->belongsToMany(Feed::class, 'users_live_feeds')
        ->withPivot('times')->orderByPivot('feed_id', 'desc');

    }

    public function customPackage()
    {
        return $this->hasOne(UserPackage::class);
    }

    public function feeds()
    {
        return $this->hasMany(Feed::class);
    }

    public function bannedUsers()
    {
        return $this->belongsToMany(User::class, 'user_banned', 'user_id', 'banned_user_id');
    }

    public function likes()
    {
        return $this->belongsToMany(Feed::class, 'users_feeds_like');
    }

    public function views()
    {
        return $this->belongsToMany(Feed::class, 'users_feeds_view');
    }

    public function audioLike()
    {
        return $this->belongsToMany(Media::class, 'user_audio_like')->withTimestamps()->orderByPivot('created_at', 'desc');
    }

    public function purchases()
    {
        return $this->belongsToMany(Feed::class, 'user_feed_purchase')->withPivot('amount')->withTimestamps()->orderByPivot('created_at', 'desc');
    }

    public function subscribers()
    {
        return $this->belongsToMany(User::class, 'users_subscribers', 'user_id', 'subscriber_id')->withPivot('leader');
    }
    public function subscriber_reverse()
    {
        return $this->belongsToMany(User::class, 'users_subscribers',  'subscriber_id', 'user_id')->withPivot('leader');
    }

    public function subscribersOn()
    {
        return $this->belongsToMany(User::class, 'users_subscribers', 'user_id', 'subscriber_id')->withPivot('leader')->wherePivot('leader', 1);
    }
    public function subscribersOff()
    {
        return $this->belongsToMany(User::class, 'users_subscribers', 'user_id', 'subscriber_id')->withPivot('leader')->wherePivot('leader', 0);
    }

    public function chat_rooms()
    {
        return $this->belongsToMany(ChatRoom::class, 'user_chat_room');
    }


    public function votes()
    {
        return $this->belongsToMany(Vote::class)->withPivot('payment');
    }

    // подписки
    public function subscription()
    {
        return $this->hasMany(Subscription::class)->orderBy('ends_at', 'desc');
    }

    public function getNameAttribute()
    {
        if ($this->last_name) {
            return $this->first_name . ' ' . $this->last_name;
        }
        return $this->first_name;
    }

    public function setPasswordAttribute($password)
    {
        $this->attributes['password'] = Hash::needsRehash($password) ? Hash::make($password) : $password;
    }

    public function checkClosedAccess()
    {

        $active_subscription = SubscriptionService::activeSubscription();
        $has_subscription = SubscriptionService::hasSubscription();

        if($has_subscription > 0 && !$active_subscription){
            //имел подписку, нужно продлить
            return true;
        }elseif ($this->created_at->diffInMinutes(now()) > self::CHECKTIMEUSER && !$active_subscription) {
            // пользователь только зарегался, закрываем доступ
            return true;
        }

        return false;
    }

    public function testPeriodCheck()
    {
        $has_subscription = SubscriptionService::hasSubscription();
        if( $has_subscription === 0 && ($this->created_at->diffInMinutes(now()) <= self::CHECKTIMEUSER) ){
            return true;
        }
        return false;
    }

    public function scopeFilter($query, array $filters)
    {
        $query->when($filters['search'] ?? null, function ($query, $search) {
            $query->where(function ($query) use ($search) {
                $query->where('first_name', 'ilike', '%'.$search.'%')
                    ->orWhere('last_name', 'ilike', '%'.$search.'%');
            });
        })->when($filters['sex'] ?? null, function ($query, $sex) {
            $query->where('sex', $sex);
        });
    }

    public function isVerified()
    {
        return $this->passport_verified;
        // return $this->phone && $this->phone_verified;
    }
    public function isVerifiedForWithdrawal()
    {
        return $this->passport_verified && $this->inn && $this->checking_account && $this->bik;
        // return $this->phone && $this->phone_verified;
    }


}
