<?php

namespace App;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;


class User extends Authenticatable
{
    use Notifiable, SoftDeletes;


    protected $fillable = [
        'email', 'password', 'organisation', 'first_name', 'last_name', 'full_name', 'date_of_birth', 'location','sender_id','is_locked','company_id',
        'phone_number', 'website_url', 'username', 'role_id', 'created_by', 'status', 'pass', 'must_change_password','avatar','google_id','name'
    ];


    protected $hidden = [
        'password', 'remember_token',
    ];

    protected $dates = ['deleted_at'];

    protected $appends = ['currency'];

    public function mailFolders(){
        return $this->hasMany(MailFolder::class,'user_id');
    }

    public function mail_api()
    {
        return $this->hasMany(MailApi::class);
    }

    public function saved_messages()
    {
        return $this->hasMany(SavedMessage::class);
    }

    public function getCurrencyAttribute()
    {
        $temp = $this->userCurrency ? $this->userCurrency->currency : Currency::whereDefault(true)->firstOrFail();
        return $temp->abbr;
    }

    public function campaign_address()
    {
        return $this->hasOne(CampaignAddress::class);
    }

    public function user_templates()
    {
        return $this->hasMany(Email_templates::class,'client_id');
    }

    public function mail_payments()
    {
        return $this->hasMany(MailPayment::class);
    }

    public function subscription()
    {
        return $this->hasOne(UserMailSubscription::class);
    }

    public function social_subscription()
    {
        return $this->hasOne(UserSocialSubscription::class);
    }

    public function balance()
    {
        return $this->hasOne(SubscriptionBalance::class);
    }


    public function social_balance()
    {
        return $this->hasOne(SocialSubscriptionBalance::class);
    }

    public function email_pricing()
    {
        return $this->hasMany(EmailPricing::class);
    }


    public function media_price()
    {
        return $this->hasMany(MediaPrice::class);
    }


    public function subscriptionIsValid()   //for checking if the subscription is valid
    {
        $now = Carbon::parse(now());
        $subscription = $this->subscription()->newQuery()->first();
        return isset($subscription) && ($now < $subscription->expires_on);
    }

    public function subscriberCount()
    {
        // Add deleted mail contacts since after pushing a mail campaign and its successful,...
        // we delete the mail contacts
        $count = 0;
        $this->mailing_list()->newQuery()->each(function ($list) use (&$count){
            $count += $list->subscribers()->withTrashed()->where('status','=','subscribed')->distinct('email_address')->count('email_address');
//            $count += $list->subscribers->count();
        });
        return $count;
    }

    public function emailSentCount()  //counts for sent mails via campaigns via audience via subscribers
    {
        try {

            return $this->user_email_campaigns()->newQuery()->withTrashed()->where('email_pricing_id',$this->subscription->email_pricing_id)
                ->where('is_sent',true)->count();
        }catch (\Exception $ex)
        {
            return  0;
        }
    }


    public function emailSentCountOld()  //counts for sent mails via campaigns via audience via subscribers
    {
        try {

            $count = 0;
            $this->user_email_campaigns()->newQuery()->withTrashed()->where('email_pricing_id',$this->subscription->email_pricing_id)
                ->where('is_sent',true)
                ->each(function ($campaign) use (&$count){
                    if (isset($campaign->user_mailing_list)){
                        if (isset($campaign->user_mailing_list->subscribers)){
                            $count += $campaign->user_mailing_list->subscribers()->withTrashed()->where('status', '=', 'subscribed')->count();
//                      $count += $campaign->user_mailing_list->subscribers->count();
                        }
                        else{ $count += 0;}
                    } else { $count += 0; }
                });
            return $count;
        }catch (\Exception $ex)
        {
            return  0;
        }
    }

    public function subscriptionLimits()
    {
        $limits =  null;
        $subscription = $this->subscription()->newQuery()->first();  //gets the current subscription
        $is_valid = $this->subscriptionIsValid();  // check if the subscription is valid

        if(isset($subscription->email_pricing))
            $limits = (object) [
                'no_contacts' =>$subscription->email_pricing->no_contacts,
                'no_audience' =>$subscription->email_pricing->no_audience,
                'no_emails'   =>$subscription->email_pricing->no_emails
            ]; //converts them to object

        return $is_valid ? $limits : null;  //return limit values
    }




    public function SocialSubscriptionIsValid()   //for checking if the subscription is valid
    {
        $now = Carbon::parse(now());
        $subscription = $this->social_subscription()->newQuery()->first();
        return isset($subscription) && ($now < $subscription->expires_on);
    }

    public function SocialSubscriptionLimits()
    {
        $limits =  null;
        $subscription = $this->social_subscription()->newQuery()->first();  //gets the current subscription
        $is_valid = $this->SocialSubscriptionIsValid();  // check if the subscription is valid

        if(isset($subscription->media_price))
            $limits = (object) [
                'no_of_post' =>$subscription->media_price->no_of_post,
            ]; //converts them to object

        return $is_valid ? $limits : null;  //return limit values
    }






    public function postBalance()
    {
       return $this->posts()->whereMonth('created_at',now())
           ->where('status','success')
           ->count();
    }


    public function ussdSubscriptionIsValid()   //for checking if the subscription is valid
    {
        $now = Carbon::parse(now());
        $subscription = $this->ussd_subscription()->newQuery()->first();
        return isset($subscription) && ($now < $subscription->expires_on);
    }


    public function ussd_subscription()
    {
        return $this->hasOne(ResellerUssdSubscription::class);
    }


    public function ussd_price()
    {
        return $this->hasMany(UssdPrice::class);
    }

    public function ussdSubscriptionLimits()
    {
        $limits =  null;
        $subscription = $this->ussd_subscription()->newQuery()->first();  //gets the current subscription
        $is_valid = $this->ussdSubscriptionIsValid();  // check if the subscription is valid
        if(isset($subscription->ussd_price))
        $limits = (object) [
                'sessions' => $subscription->ussd_price->sessions,
            ]; //converts them to object

        return $is_valid ? $limits : null;  //return limit values
    }

    public function ussd_balance()
    {
        return $this->hasOne(UssdSubscriptionBalance::class);
    }


    public function under_reseller()
    {
        return $this->created_by !='npontu';
    }

    public function getReseller(){

        $reseller = $this->under_reseller() ? User::query()->where('username', $this->created_by)->first() : null;
        return $reseller;
    }

    public function reseller()
    {
        return $this->under_reseller() ? User::query()->where('username',$this->created_by)->first() : null;
    }

    public function resellers_client()
    {
        return $this->newQuery()->where('created_by',$this->username)->get();  //get resellers clients
    }


    public function socialCredit()
    {
        return $this->hasOne(SocialMediaCredit::class);
    }

    public function mailing_list()
    {
        return $this->hasMany(UserMailingList::class);
    }

    public function user_email_campaigns() {
        return $this->hasMany(UserEmailCampaign::class);
    }

    public function role() {
        return $this->belongsTo('App\Role');
    }

    public function company()
    {
        return $this->hasOne(Company::class);
    }


    public function sender_ids()
    {
        return $this->hasMany(UserSenderId::class);
    }

    public function social()
    {
        return $this->hasMany(UserSocial::class);

    }

    public function trail($message)
    {
        $message = ucwords($message);

        AuditTrail::query()->create([
            'user_id'   => $this->id,
            'username'  => $this->username,
            'date'      => Carbon::now()->toDateTimeString(),
            'activity'  => $this->first_name.' '.$this->last_name. ": {$message}"
        ]);
    }

    public function posts()
    {
        return $this->hasMany(UserPost::class);
    }


    public function admin_access_rights()
    {
        return $this->hasOne('App\AdminAccessRight');
    }

    public function userCurrency() {
        return $this->hasOne('App\UserCurrency');
    }

    public function picture() {
        return $this->hasOne('App\Picture');
    }

    public function user_networks() {
        return $this->hasMany('App\UserNetwork');
    }

    public function credit() {
        return $this->hasOne('App\Credit');
    }

    public function creditHistory() {
        return $this->hasMany('App\CreditHistory');
    }

    public function jobs() {
        return $this->hasMany('App\UserJob');
    }

    public function email_jobs() {
        return $this->hasMany('App\EmailJob');
    }

    public function contacts() {
        return $this->hasMany('App\Contact');
    }

    public function tmp_group_sms() {
        return $this->hasMany('App\TmpGroupSms');
    }

    public function tmp_group_emails() {
        return $this->hasMany('App\TmpGroupEmail');
    }

    public function groups() {
        return $this->hasMany('App\ContactGroup');
    }

    public function rejected_sms() {
        return $this->hasMany('App\RejectedSms');
    }

    public function pending_single_sms() {
        return $this->hasMany('App\PendingSingleSms');
    }

    public function pending_single_email() {
        return $this->hasMany('App\PendingSingleEmail');
    }

    public function reports() {
        return $this->hasMany('App\Report');
    }

    public function audit_trails() {
        return $this->hasMany('App\AuditTrail');
    }

    public function sms_images() {
        return $this->hasMany('App\SmsImage');
    }

    public function logs() {
        return $this->hasMany('App\Log');
    }

    public function email_logs() {
        return $this->hasMany('App\EmailLog');
    }

    public function queue_messages() {
        return $this->hasMany('App\QueueMessage');
    }

    public function audiences() {
        return $this->hasMany('App\Audience');
    }

    public function stanbic_users() {
        return $this->hasMany('App\StanbicUser');
    }

    public function password_expiration(){
        return $this->hasOne('App\PasswordExpiration');
    }

    public function ai_tones(){
        return $this->hasMany(AiTone::class);
    }

}
